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;
16 use rls_data::{self, Id, Analysis, Import, ImportKind, Def, DefKind, Ref, RefKind, MacroRef,
17 Relation, RelationKind, Signature, SigElement, CratePreludeData};
18 use rls_span::{Column, Row};
22 use data::{self, VariableKind};
25 pub struct JsonDumper<'b, W: Write + 'b> {
30 impl<'b, W: Write> JsonDumper<'b, W> {
31 pub fn new(writer: &'b mut W) -> JsonDumper<'b, W> {
32 JsonDumper { output: writer, result: Analysis::new() }
36 impl<'b, W: Write> Drop for JsonDumper<'b, W> {
38 if let Err(_) = write!(self.output, "{}", as_json(&self.result)) {
39 error!("Error writing output");
44 macro_rules! impl_fn {
45 ($fn_name: ident, $data_type: ident, $bucket: ident) => {
46 fn $fn_name(&mut self, data: $data_type) {
47 self.result.$bucket.push(data.into());
52 impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
53 fn crate_prelude(&mut self, data: CratePreludeData) {
54 self.result.prelude = Some(data)
57 impl_fn!(extern_crate, ExternCrateData, imports);
58 impl_fn!(use_data, UseData, imports);
59 impl_fn!(use_glob, UseGlobData, imports);
61 impl_fn!(enum_data, EnumData, defs);
62 impl_fn!(tuple_variant, TupleVariantData, defs);
63 impl_fn!(struct_variant, StructVariantData, defs);
64 impl_fn!(struct_data, StructData, defs);
65 impl_fn!(trait_data, TraitData, defs);
66 impl_fn!(function, FunctionData, defs);
67 impl_fn!(method, MethodData, defs);
68 impl_fn!(macro_data, MacroData, defs);
69 impl_fn!(typedef, TypeDefData, defs);
70 impl_fn!(variable, VariableData, defs);
72 impl_fn!(function_ref, FunctionRefData, refs);
73 impl_fn!(function_call, FunctionCallData, refs);
74 impl_fn!(method_call, MethodCallData, refs);
75 impl_fn!(mod_ref, ModRefData, refs);
76 impl_fn!(type_ref, TypeRefData, refs);
77 impl_fn!(variable_ref, VariableRefData, refs);
79 impl_fn!(macro_use, MacroUseData, macro_refs);
81 fn mod_data(&mut self, data: ModData) {
82 let id: Id = id_from_def_id(data.id);
86 span: data.span.into(),
88 qualname: data.qualname,
91 children: data.items.into_iter().map(|id| id_from_def_id(id)).collect(),
94 sig: Some(data.sig.into()),
95 attributes: data.attributes.into_iter().map(|a| a.into()).collect(),
97 if def.span.file_name.to_str().unwrap() != def.value {
98 // If the module is an out-of-line defintion, then we'll make the
99 // defintion the first character in the module's file and turn the
100 // the declaration into a reference to it.
106 self.result.refs.push(rf);
107 def.span = rls_data::SpanData {
108 file_name: def.value.clone().into(),
111 line_start: Row::new_one_indexed(1),
112 line_end: Row::new_one_indexed(1),
113 column_start: Column::new_one_indexed(1),
114 column_end: Column::new_one_indexed(1),
118 self.result.defs.push(def);
121 fn impl_data(&mut self, data: ImplData) {
122 if data.self_ref.is_some() {
123 self.result.relations.push(data.into());
126 fn inheritance(&mut self, data: InheritanceData) {
127 self.result.relations.push(data.into());
131 // FIXME do we want to change ExternalData to this mode? It will break DXR.
132 // FIXME methods. The defs have information about possible overriding and the
133 // refs have decl information (e.g., a trait method where we know the required
134 // method, but not the supplied method). In both cases, we are currently
137 // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
138 // we use our own Id which is the same, but without the newtype.
139 fn id_from_def_id(id: DefId) -> Id {
141 krate: id.krate.as_u32(),
142 index: id.index.as_u32(),
146 impl Into<Import> for ExternCrateData {
147 fn into(self) -> Import {
149 kind: ImportKind::ExternCrate,
153 value: String::new(),
157 impl Into<Import> for UseData {
158 fn into(self) -> Import {
160 kind: ImportKind::Use,
161 ref_id: self.mod_id.map(|id| id_from_def_id(id)),
164 value: String::new(),
168 impl Into<Import> for UseGlobData {
169 fn into(self) -> Import {
171 kind: ImportKind::GlobUse,
174 name: "*".to_owned(),
175 value: self.names.join(", "),
180 impl Into<Def> for EnumData {
181 fn into(self) -> Def {
184 id: id_from_def_id(self.id),
187 qualname: self.qualname,
190 children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(),
193 sig: Some(self.sig.into()),
194 attributes: self.attributes,
199 impl Into<Def> for TupleVariantData {
200 fn into(self) -> Def {
202 kind: DefKind::Tuple,
203 id: id_from_def_id(self.id),
206 qualname: self.qualname,
212 sig: Some(self.sig.into()),
213 attributes: self.attributes,
217 impl Into<Def> for StructVariantData {
218 fn into(self) -> Def {
220 kind: DefKind::Struct,
221 id: id_from_def_id(self.id),
224 qualname: self.qualname,
230 sig: Some(self.sig.into()),
231 attributes: self.attributes,
235 impl Into<Def> for StructData {
236 fn into(self) -> Def {
238 kind: DefKind::Struct,
239 id: id_from_def_id(self.id),
242 qualname: self.qualname,
245 children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(),
248 sig: Some(self.sig.into()),
249 attributes: self.attributes,
253 impl Into<Def> for TraitData {
254 fn into(self) -> Def {
256 kind: DefKind::Trait,
257 id: id_from_def_id(self.id),
260 qualname: self.qualname,
263 children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
266 sig: Some(self.sig.into()),
267 attributes: self.attributes,
271 impl Into<Def> for FunctionData {
272 fn into(self) -> Def {
274 kind: DefKind::Function,
275 id: id_from_def_id(self.id),
278 qualname: self.qualname,
284 sig: Some(self.sig.into()),
285 attributes: self.attributes,
289 impl Into<Def> for MethodData {
290 fn into(self) -> Def {
292 kind: DefKind::Method,
293 id: id_from_def_id(self.id),
296 qualname: self.qualname,
300 decl_id: self.decl_id.map(|id| id_from_def_id(id)),
302 sig: Some(self.sig.into()),
303 attributes: self.attributes,
307 impl Into<Def> for MacroData {
308 fn into(self) -> Def {
310 kind: DefKind::Macro,
311 id: id_from_def_id(null_def_id()),
314 qualname: self.qualname,
315 value: String::new(),
325 impl Into<Def> for TypeDefData {
326 fn into(self) -> Def {
329 id: id_from_def_id(self.id),
332 qualname: self.qualname,
338 sig: self.sig.map(|s| s.into()),
339 attributes: self.attributes,
343 impl Into<Def> for VariableData {
344 fn into(self) -> Def {
346 kind: match self.kind {
347 VariableKind::Static => DefKind::Static,
348 VariableKind::Const => DefKind::Const,
349 VariableKind::Local => DefKind::Local,
350 VariableKind::Field => DefKind::Field,
352 id: id_from_def_id(self.id),
355 qualname: self.qualname,
356 value: self.type_value,
362 attributes: self.attributes,
367 impl Into<Ref> for FunctionRefData {
368 fn into(self) -> Ref {
370 kind: RefKind::Function,
372 ref_id: id_from_def_id(self.ref_id),
376 impl Into<Ref> for FunctionCallData {
377 fn into(self) -> Ref {
379 kind: RefKind::Function,
381 ref_id: id_from_def_id(self.ref_id),
385 impl Into<Ref> for MethodCallData {
386 fn into(self) -> Ref {
388 kind: RefKind::Function,
390 ref_id: id_from_def_id(self.ref_id.or(self.decl_id).unwrap_or(null_def_id())),
394 impl Into<Ref> for ModRefData {
395 fn into(self) -> Ref {
399 ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
403 impl Into<Ref> for TypeRefData {
404 fn into(self) -> Ref {
408 ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
412 impl Into<Ref> for VariableRefData {
413 fn into(self) -> Ref {
415 kind: RefKind::Variable,
417 ref_id: id_from_def_id(self.ref_id),
422 impl Into<MacroRef> for MacroUseData {
423 fn into(self) -> MacroRef {
426 qualname: self.qualname,
427 callee_span: self.callee_span.into(),
432 impl Into<Relation> for ImplData {
433 fn into(self) -> Relation {
436 kind: RelationKind::Impl,
437 from: id_from_def_id(self.self_ref.unwrap_or(null_def_id())),
438 to: id_from_def_id(self.trait_ref.unwrap_or(null_def_id())),
443 impl Into<Relation> for InheritanceData {
444 fn into(self) -> Relation {
447 kind: RelationKind::SuperTrait,
448 from: id_from_def_id(self.base_id),
449 to: id_from_def_id(self.deriv_id),
454 impl Into<Signature> for external_data::Signature {
455 fn into(self) -> Signature {
459 ident_start: self.ident_start,
460 ident_end: self.ident_end,
461 defs: self.defs.into_iter().map(|s| s.into()).collect(),
462 refs: self.refs.into_iter().map(|s| s.into()).collect(),
467 impl Into<SigElement> for data::SigElement {
468 fn into(self) -> SigElement {
470 id: id_from_def_id(self.id),