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<O: DumpOutput> {
30 pub trait DumpOutput {
31 fn dump(&mut self, result: &Analysis);
34 pub struct WriteOutput<'b, W: Write + 'b> {
38 impl<'b, W: Write> DumpOutput for WriteOutput<'b, W> {
39 fn dump(&mut self, result: &Analysis) {
40 if let Err(_) = write!(self.output, "{}", as_json(&result)) {
41 error!("Error writing output");
46 pub struct CallbackOutput<'b> {
47 callback: &'b mut FnMut(&Analysis),
50 impl<'b> DumpOutput for CallbackOutput<'b> {
51 fn dump(&mut self, result: &Analysis) {
52 (self.callback)(result)
56 impl<'b, W: Write> JsonDumper<WriteOutput<'b, W>> {
57 pub fn new(writer: &'b mut W) -> JsonDumper<WriteOutput<'b, W>> {
58 JsonDumper { output: WriteOutput { output: writer }, result: Analysis::new() }
62 impl<'b> JsonDumper<CallbackOutput<'b>> {
63 pub fn with_callback(callback: &'b mut FnMut(&Analysis)) -> JsonDumper<CallbackOutput<'b>> {
64 JsonDumper { output: CallbackOutput { callback: callback }, result: Analysis::new() }
68 impl<O: DumpOutput> Drop for JsonDumper<O> {
70 self.output.dump(&self.result);
74 macro_rules! impl_fn {
75 ($fn_name: ident, $data_type: ident, $bucket: ident) => {
76 fn $fn_name(&mut self, data: $data_type) {
77 self.result.$bucket.push(data.into());
82 impl<'b, O: DumpOutput + 'b> Dump for JsonDumper<O> {
83 fn crate_prelude(&mut self, data: CratePreludeData) {
84 self.result.prelude = Some(data)
87 impl_fn!(extern_crate, ExternCrateData, imports);
88 impl_fn!(use_data, UseData, imports);
89 impl_fn!(use_glob, UseGlobData, imports);
91 impl_fn!(enum_data, EnumData, defs);
92 impl_fn!(tuple_variant, TupleVariantData, defs);
93 impl_fn!(struct_variant, StructVariantData, defs);
94 impl_fn!(struct_data, StructData, defs);
95 impl_fn!(trait_data, TraitData, defs);
96 impl_fn!(function, FunctionData, defs);
97 impl_fn!(method, MethodData, defs);
98 impl_fn!(macro_data, MacroData, defs);
99 impl_fn!(typedef, TypeDefData, defs);
100 impl_fn!(variable, VariableData, defs);
102 impl_fn!(function_ref, FunctionRefData, refs);
103 impl_fn!(function_call, FunctionCallData, refs);
104 impl_fn!(method_call, MethodCallData, refs);
105 impl_fn!(mod_ref, ModRefData, refs);
106 impl_fn!(type_ref, TypeRefData, refs);
107 impl_fn!(variable_ref, VariableRefData, refs);
109 impl_fn!(macro_use, MacroUseData, macro_refs);
111 fn mod_data(&mut self, data: ModData) {
112 let id: Id = id_from_def_id(data.id);
116 span: data.span.into(),
118 qualname: data.qualname,
119 value: data.filename,
121 children: data.items.into_iter().map(|id| id_from_def_id(id)).collect(),
124 sig: data.sig.map(|s| s.into()),
125 attributes: data.attributes.into_iter().map(|a| a.into()).collect(),
127 if def.span.file_name.to_str().unwrap() != def.value {
128 // If the module is an out-of-line defintion, then we'll make the
129 // defintion the first character in the module's file and turn the
130 // the declaration into a reference to it.
136 self.result.refs.push(rf);
137 def.span = rls_data::SpanData {
138 file_name: def.value.clone().into(),
141 line_start: Row::new_one_indexed(1),
142 line_end: Row::new_one_indexed(1),
143 column_start: Column::new_one_indexed(1),
144 column_end: Column::new_one_indexed(1),
148 self.result.defs.push(def);
151 fn impl_data(&mut self, data: ImplData) {
152 if data.self_ref.is_some() {
153 self.result.relations.push(data.into());
156 fn inheritance(&mut self, data: InheritanceData) {
157 self.result.relations.push(data.into());
161 // FIXME do we want to change ExternalData to this mode? It will break DXR.
162 // FIXME methods. The defs have information about possible overriding and the
163 // refs have decl information (e.g., a trait method where we know the required
164 // method, but not the supplied method). In both cases, we are currently
167 // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
168 // we use our own Id which is the same, but without the newtype.
169 pub fn id_from_def_id(id: DefId) -> Id {
171 krate: id.krate.as_u32(),
172 index: id.index.as_u32(),
176 impl Into<Import> for ExternCrateData {
177 fn into(self) -> Import {
179 kind: ImportKind::ExternCrate,
183 value: String::new(),
187 impl Into<Import> for UseData {
188 fn into(self) -> Import {
190 kind: ImportKind::Use,
191 ref_id: self.mod_id.map(|id| id_from_def_id(id)),
194 value: String::new(),
198 impl Into<Import> for UseGlobData {
199 fn into(self) -> Import {
201 kind: ImportKind::GlobUse,
204 name: "*".to_owned(),
205 value: self.names.join(", "),
210 impl Into<Def> for EnumData {
211 fn into(self) -> Def {
214 id: id_from_def_id(self.id),
217 qualname: self.qualname,
220 children: self.variants.into_iter().map(|id| id_from_def_id(id)).collect(),
223 sig: Some(self.sig.into()),
224 attributes: self.attributes,
229 impl Into<Def> for TupleVariantData {
230 fn into(self) -> Def {
232 kind: DefKind::Tuple,
233 id: id_from_def_id(self.id),
236 qualname: self.qualname,
242 sig: Some(self.sig.into()),
243 attributes: self.attributes,
247 impl Into<Def> for StructVariantData {
248 fn into(self) -> Def {
250 kind: DefKind::Struct,
251 id: id_from_def_id(self.id),
254 qualname: self.qualname,
260 sig: Some(self.sig.into()),
261 attributes: self.attributes,
265 impl Into<Def> for StructData {
266 fn into(self) -> Def {
268 kind: DefKind::Struct,
269 id: id_from_def_id(self.id),
272 qualname: self.qualname,
275 children: self.fields.into_iter().map(|id| id_from_def_id(id)).collect(),
278 sig: Some(self.sig.into()),
279 attributes: self.attributes,
283 impl Into<Def> for TraitData {
284 fn into(self) -> Def {
286 kind: DefKind::Trait,
287 id: id_from_def_id(self.id),
290 qualname: self.qualname,
293 children: self.items.into_iter().map(|id| id_from_def_id(id)).collect(),
296 sig: Some(self.sig.into()),
297 attributes: self.attributes,
301 impl Into<Def> for FunctionData {
302 fn into(self) -> Def {
304 kind: DefKind::Function,
305 id: id_from_def_id(self.id),
308 qualname: self.qualname,
314 sig: Some(self.sig.into()),
315 attributes: self.attributes,
319 impl Into<Def> for MethodData {
320 fn into(self) -> Def {
322 kind: DefKind::Method,
323 id: id_from_def_id(self.id),
326 qualname: self.qualname,
330 decl_id: self.decl_id.map(|id| id_from_def_id(id)),
332 sig: Some(self.sig.into()),
333 attributes: self.attributes,
337 impl Into<Def> for MacroData {
338 fn into(self) -> Def {
340 kind: DefKind::Macro,
341 id: id_from_def_id(null_def_id()),
344 qualname: self.qualname,
345 value: String::new(),
355 impl Into<Def> for TypeDefData {
356 fn into(self) -> Def {
359 id: id_from_def_id(self.id),
362 qualname: self.qualname,
368 sig: self.sig.map(|s| s.into()),
369 attributes: self.attributes,
373 impl Into<Def> for VariableData {
374 fn into(self) -> Def {
376 kind: match self.kind {
377 VariableKind::Static => DefKind::Static,
378 VariableKind::Const => DefKind::Const,
379 VariableKind::Local => DefKind::Local,
380 VariableKind::Field => DefKind::Field,
382 id: id_from_def_id(self.id),
385 qualname: self.qualname,
386 value: self.type_value,
392 attributes: self.attributes,
397 impl Into<Ref> for FunctionRefData {
398 fn into(self) -> Ref {
400 kind: RefKind::Function,
402 ref_id: id_from_def_id(self.ref_id),
406 impl Into<Ref> for FunctionCallData {
407 fn into(self) -> Ref {
409 kind: RefKind::Function,
411 ref_id: id_from_def_id(self.ref_id),
415 impl Into<Ref> for MethodCallData {
416 fn into(self) -> Ref {
418 kind: RefKind::Function,
420 ref_id: id_from_def_id(self.ref_id.or(self.decl_id).unwrap_or(null_def_id())),
424 impl Into<Ref> for ModRefData {
425 fn into(self) -> Ref {
429 ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
433 impl Into<Ref> for TypeRefData {
434 fn into(self) -> Ref {
438 ref_id: id_from_def_id(self.ref_id.unwrap_or(null_def_id())),
442 impl Into<Ref> for VariableRefData {
443 fn into(self) -> Ref {
445 kind: RefKind::Variable,
447 ref_id: id_from_def_id(self.ref_id),
452 impl Into<MacroRef> for MacroUseData {
453 fn into(self) -> MacroRef {
456 qualname: self.qualname,
457 callee_span: self.callee_span.into(),
462 impl Into<Relation> for ImplData {
463 fn into(self) -> Relation {
466 kind: RelationKind::Impl,
467 from: id_from_def_id(self.self_ref.unwrap_or(null_def_id())),
468 to: id_from_def_id(self.trait_ref.unwrap_or(null_def_id())),
473 impl Into<Relation> for InheritanceData {
474 fn into(self) -> Relation {
477 kind: RelationKind::SuperTrait,
478 from: id_from_def_id(self.base_id),
479 to: id_from_def_id(self.deriv_id),
484 impl Into<Signature> for external_data::Signature {
485 fn into(self) -> Signature {
489 ident_start: self.ident_start,
490 ident_end: self.ident_end,
491 defs: self.defs.into_iter().map(|s| s.into()).collect(),
492 refs: self.refs.into_iter().map(|s| s.into()).collect(),
497 impl Into<SigElement> for data::SigElement {
498 fn into(self) -> SigElement {
500 id: id_from_def_id(self.id),