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, SigElement}
;
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)]
182 sig
: Option
<JsonSignature
>,
185 #[derive(Debug, RustcEncodable)]
187 // value = variant names
189 // value = enum name + variant name + types
191 // value = [enum name +] name + fields
195 // value = type + generics
197 // value = type + generics
203 // value = aliased type
205 // value = type and init expression (for all variable kinds).
211 impl From
<EnumData
> for Option
<Def
> {
212 fn from(data
: EnumData
) -> Option
<Def
> {
213 match data
.visibility
{
214 Visibility
::Public
=> Some(Def
{
216 id
: From
::from(data
.id
),
219 qualname
: data
.qualname
,
222 children
: data
.variants
.into_iter().map(|id
| From
::from(id
)).collect(),
225 sig
: Some(From
::from(data
.sig
)),
232 impl From
<TupleVariantData
> for Option
<Def
> {
233 fn from(data
: TupleVariantData
) -> Option
<Def
> {
235 kind
: DefKind
::Tuple
,
236 id
: From
::from(data
.id
),
239 qualname
: data
.qualname
,
241 parent
: data
.parent
.map(|id
| From
::from(id
)),
245 sig
: Some(From
::from(data
.sig
)),
249 impl From
<StructVariantData
> for Option
<Def
> {
250 fn from(data
: StructVariantData
) -> Option
<Def
> {
252 kind
: DefKind
::Struct
,
253 id
: From
::from(data
.id
),
256 qualname
: data
.qualname
,
258 parent
: data
.parent
.map(|id
| From
::from(id
)),
262 sig
: Some(From
::from(data
.sig
)),
266 impl From
<StructData
> for Option
<Def
> {
267 fn from(data
: StructData
) -> Option
<Def
> {
268 match data
.visibility
{
269 Visibility
::Public
=> Some(Def
{
270 kind
: DefKind
::Struct
,
271 id
: From
::from(data
.id
),
274 qualname
: data
.qualname
,
277 children
: data
.fields
.into_iter().map(|id
| From
::from(id
)).collect(),
280 sig
: Some(From
::from(data
.sig
)),
286 impl From
<TraitData
> for Option
<Def
> {
287 fn from(data
: TraitData
) -> Option
<Def
> {
288 match data
.visibility
{
289 Visibility
::Public
=> Some(Def
{
290 kind
: DefKind
::Trait
,
291 id
: From
::from(data
.id
),
294 qualname
: data
.qualname
,
296 children
: data
.items
.into_iter().map(|id
| From
::from(id
)).collect(),
300 sig
: Some(From
::from(data
.sig
)),
306 impl From
<FunctionData
> for Option
<Def
> {
307 fn from(data
: FunctionData
) -> Option
<Def
> {
308 match data
.visibility
{
309 Visibility
::Public
=> Some(Def
{
310 kind
: DefKind
::Function
,
311 id
: From
::from(data
.id
),
314 qualname
: data
.qualname
,
317 parent
: data
.parent
.map(|id
| From
::from(id
)),
320 sig
: Some(From
::from(data
.sig
)),
326 impl From
<MethodData
> for Option
<Def
> {
327 fn from(data
: MethodData
) -> Option
<Def
> {
328 match data
.visibility
{
329 Visibility
::Public
=> Some(Def
{
330 kind
: DefKind
::Method
,
331 id
: From
::from(data
.id
),
334 qualname
: data
.qualname
,
337 parent
: data
.parent
.map(|id
| From
::from(id
)),
338 decl_id
: data
.decl_id
.map(|id
| From
::from(id
)),
340 sig
: Some(From
::from(data
.sig
)),
346 impl From
<MacroData
> for Option
<Def
> {
347 fn from(data
: MacroData
) -> Option
<Def
> {
349 kind
: DefKind
::Macro
,
350 id
: From
::from(null_def_id()),
353 qualname
: data
.qualname
,
354 value
: String
::new(),
363 impl From
<ModData
> for Option
<Def
> {
364 fn from(data
:ModData
) -> Option
<Def
> {
365 match data
.visibility
{
366 Visibility
::Public
=> Some(Def
{
368 id
: From
::from(data
.id
),
371 qualname
: data
.qualname
,
372 value
: data
.filename
,
373 children
: data
.items
.into_iter().map(|id
| From
::from(id
)).collect(),
377 sig
: Some(From
::from(data
.sig
)),
383 impl From
<TypeDefData
> for Option
<Def
> {
384 fn from(data
: TypeDefData
) -> Option
<Def
> {
385 match data
.visibility
{
386 Visibility
::Public
=> Some(Def
{
388 id
: From
::from(data
.id
),
391 qualname
: data
.qualname
,
394 parent
: data
.parent
.map(|id
| From
::from(id
)),
397 sig
: data
.sig
.map(|s
| From
::from(s
)),
404 impl From
<VariableData
> for Option
<Def
> {
405 fn from(data
: VariableData
) -> Option
<Def
> {
406 match data
.visibility
{
407 Visibility
::Public
=> Some(Def
{
408 kind
: match data
.kind
{
409 VariableKind
::Static
=> DefKind
::Static
,
410 VariableKind
::Const
=> DefKind
::Const
,
411 VariableKind
::Local
=> { return None }
412 VariableKind
::Field
=> DefKind
::Field
,
414 id
: From
::from(data
.id
),
417 qualname
: data
.qualname
,
420 parent
: data
.parent
.map(|id
| From
::from(id
)),
423 sig
: data
.sig
.map(|s
| From
::from(s
)),
430 #[derive(Debug, RustcEncodable)]
431 pub struct JsonSignature
{
436 defs
: Vec
<JsonSigElement
>,
437 refs
: Vec
<JsonSigElement
>,
440 impl From
<Signature
> for JsonSignature
{
441 fn from(data
: Signature
) -> JsonSignature
{
445 ident_start
: data
.ident_start
,
446 ident_end
: data
.ident_end
,
447 defs
: data
.defs
.into_iter().map(|s
| From
::from(s
)).collect(),
448 refs
: data
.refs
.into_iter().map(|s
| From
::from(s
)).collect(),
453 #[derive(Debug, RustcEncodable)]
454 pub struct JsonSigElement
{
460 impl From
<SigElement
> for JsonSigElement
{
461 fn from(data
: SigElement
) -> JsonSigElement
{
463 id
: From
::from(data
.id
),