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_serialize::json::as_json;
16 use data::{VariableKind, Visibility};
20 use rls_data::{Analysis, Import, ImportKind, Def, DefKind, CratePreludeData, Format};
23 // A dumper to dump a restricted set of JSON information, designed for use with
24 // libraries distributed without their source. Clients are likely to use type
25 // information here, and (for example) generate Rustdoc URLs, but don't need
26 // information for navigating the source of the crate.
27 // Relative to the regular JSON save-analysis info, this form is filtered to
28 // remove non-visible items.
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 let mut result = Analysis::new();
37 result.kind = Format::JsonApi;
38 JsonApiDumper { output: writer, result }
42 impl<'b, W: Write> Drop for JsonApiDumper<'b, W> {
44 if let Err(_) = write!(self.output, "{}", as_json(&self.result)) {
45 error!("Error writing output");
50 macro_rules! impl_fn {
51 ($fn_name: ident, $data_type: ident, $bucket: ident) => {
52 fn $fn_name(&mut self, data: $data_type) {
53 if let Some(datum) = data.into() {
54 self.result.$bucket.push(datum);
60 impl<'b, W: Write + 'b> Dump for JsonApiDumper<'b, W> {
61 fn crate_prelude(&mut self, data: CratePreludeData) {
62 self.result.prelude = Some(data)
65 impl_fn!(use_data, UseData, imports);
66 impl_fn!(use_glob, UseGlobData, imports);
68 impl_fn!(enum_data, EnumData, defs);
69 impl_fn!(tuple_variant, TupleVariantData, defs);
70 impl_fn!(struct_variant, StructVariantData, defs);
71 impl_fn!(struct_data, StructData, defs);
72 impl_fn!(trait_data, TraitData, defs);
73 impl_fn!(function, FunctionData, defs);
74 impl_fn!(method, MethodData, defs);
75 impl_fn!(macro_data, MacroData, defs);
76 impl_fn!(mod_data, ModData, defs);
77 impl_fn!(typedef, TypeDefData, defs);
78 impl_fn!(variable, VariableData, defs);
80 fn impl_data(&mut self, data: ImplData) {
81 if data.self_ref.is_some() {
82 self.result.relations.push(data.into());
85 fn inheritance(&mut self, data: InheritanceData) {
86 self.result.relations.push(data.into());
90 // FIXME methods. The defs have information about possible overriding and the
91 // refs have decl information (e.g., a trait method where we know the required
92 // method, but not the supplied method). In both cases, we are currently
95 impl Into<Option<Import>> for UseData {
96 fn into(self) -> Option<Import> {
97 match self.visibility {
98 Visibility::Public => Some(Import {
99 kind: ImportKind::Use,
100 ref_id: self.mod_id.map(|id| id_from_def_id(id)),
103 value: String::new(),
109 impl Into<Option<Import>> for UseGlobData {
110 fn into(self) -> Option<Import> {
111 match self.visibility {
112 Visibility::Public => Some(Import {
113 kind: ImportKind::GlobUse,
116 name: "*".to_owned(),
117 value: self.names.join(", "),
124 impl Into<Option<Def>> for EnumData {
125 fn into(self) -> Option<Def> {
126 match self.visibility {
127 Visibility::Public => Some(Def {
129 id: id_from_def_id(self.id),
132 qualname: self.qualname,
135 children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(),
146 impl Into<Option<Def>> for TupleVariantData {
147 fn into(self) -> Option<Def> {
149 kind: DefKind::Tuple,
150 id: id_from_def_id(self.id),
153 qualname: self.qualname,
155 parent: self.parent.map(|id| id_from_def_id(id)),
164 impl Into<Option<Def>> for StructVariantData {
165 fn into(self) -> Option<Def> {
167 kind: DefKind::Struct,
168 id: id_from_def_id(self.id),
171 qualname: self.qualname,
173 parent: self.parent.map(|id| id_from_def_id(id)),
182 impl Into<Option<Def>> for StructData {
183 fn into(self) -> Option<Def> {
184 match self.visibility {
185 Visibility::Public => Some(Def {
186 kind: DefKind::Struct,
187 id: id_from_def_id(self.id),
190 qualname: self.qualname,
193 children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(),
203 impl Into<Option<Def>> for TraitData {
204 fn into(self) -> Option<Def> {
205 match self.visibility {
206 Visibility::Public => Some(Def {
207 kind: DefKind::Trait,
208 id: id_from_def_id(self.id),
211 qualname: self.qualname,
213 children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
224 impl Into<Option<Def>> for FunctionData {
225 fn into(self) -> Option<Def> {
226 match self.visibility {
227 Visibility::Public => Some(Def {
228 kind: DefKind::Function,
229 id: id_from_def_id(self.id),
232 qualname: self.qualname,
235 parent: self.parent.map(|id| id_from_def_id(id)),
245 impl Into<Option<Def>> for MethodData {
246 fn into(self) -> Option<Def> {
247 match self.visibility {
248 Visibility::Public => Some(Def {
249 kind: DefKind::Method,
250 id: id_from_def_id(self.id),
253 qualname: self.qualname,
256 parent: self.parent.map(|id| id_from_def_id(id)),
257 decl_id: self.decl_id.map(|id| id_from_def_id(id)),
266 impl Into<Option<Def>> for MacroData {
267 fn into(self) -> Option<Def> {
269 kind: DefKind::Macro,
270 id: id_from_def_id(null_def_id()),
273 qualname: self.qualname,
274 value: String::new(),
284 impl Into<Option<Def>> for ModData {
285 fn into(self) -> Option<Def> {
286 match self.visibility {
287 Visibility::Public => Some(Def {
289 id: id_from_def_id(self.id),
292 qualname: self.qualname,
293 value: self.filename,
294 children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
298 sig: self.sig.map(|s| s.into()),
305 impl Into<Option<Def>> for TypeDefData {
306 fn into(self) -> Option<Def> {
307 match self.visibility {
308 Visibility::Public => Some(Def {
310 id: id_from_def_id(self.id),
313 qualname: self.qualname,
316 parent: self.parent.map(|id| id_from_def_id(id)),
319 sig: self.sig.map(|s| s.into()),
327 impl Into<Option<Def>> for VariableData {
328 fn into(self) -> Option<Def> {
329 match self.visibility {
330 Visibility::Public => Some(Def {
331 kind: match self.kind {
332 VariableKind::Static => DefKind::Static,
333 VariableKind::Const => DefKind::Const,
334 VariableKind::Local => { return None }
335 VariableKind::Field => DefKind::Field,
337 id: id_from_def_id(self.id),
340 qualname: self.qualname,
343 parent: self.parent.map(|id| id_from_def_id(id)),
346 sig: self.sig.map(|s| s.into()),