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;
15 use rls_data::{self, Analysis, CratePreludeData, Def, DefKind, Import, MacroRef, Ref, RefKind,
17 use rls_data::config::Config;
18 use rls_span::{Column, Row};
26 pub struct JsonDumper<O: DumpOutput> {
32 pub trait DumpOutput {
33 fn dump(&mut self, result: &Analysis);
36 pub struct WriteOutput<'b, W: Write + 'b> {
40 impl<'b, W: Write> DumpOutput for WriteOutput<'b, W> {
41 fn dump(&mut self, result: &Analysis) {
42 if let Err(_) = write!(self.output, "{}", as_json(&result)) {
43 error!("Error writing output");
48 pub struct CallbackOutput<'b> {
49 callback: &'b mut dyn FnMut(&Analysis),
52 impl<'b> DumpOutput for CallbackOutput<'b> {
53 fn dump(&mut self, result: &Analysis) {
54 (self.callback)(result)
58 impl<'b, W: Write> JsonDumper<WriteOutput<'b, W>> {
59 pub fn new(writer: &'b mut W, config: Config) -> JsonDumper<WriteOutput<'b, W>> {
61 output: WriteOutput { output: writer },
62 config: config.clone(),
63 result: Analysis::new(config),
68 impl<'b> JsonDumper<CallbackOutput<'b>> {
70 callback: &'b mut dyn FnMut(&Analysis),
72 ) -> JsonDumper<CallbackOutput<'b>> {
74 output: CallbackOutput { callback: callback },
75 config: config.clone(),
76 result: Analysis::new(config),
81 impl<O: DumpOutput> Drop for JsonDumper<O> {
83 self.output.dump(&self.result);
87 impl<'b, O: DumpOutput + 'b> JsonDumper<O> {
88 pub fn crate_prelude(&mut self, data: CratePreludeData) {
89 self.result.prelude = Some(data)
92 pub fn macro_use(&mut self, data: MacroRef) {
93 if self.config.pub_only || self.config.reachable_only {
96 self.result.macro_refs.push(data);
99 pub fn import(&mut self, access: &Access, import: Import) {
100 if !access.public && self.config.pub_only
101 || !access.reachable && self.config.reachable_only {
104 self.result.imports.push(import);
107 pub fn dump_ref(&mut self, data: Ref) {
108 if self.config.pub_only || self.config.reachable_only {
111 self.result.refs.push(data);
114 pub fn dump_def(&mut self, access: &Access, mut data: Def) {
115 if !access.public && self.config.pub_only
116 || !access.reachable && self.config.reachable_only {
119 if data.kind == DefKind::Mod && data.span.file_name.to_str().unwrap() != data.value {
120 // If the module is an out-of-line definition, then we'll make the
121 // definition the first character in the module's file and turn
122 // the declaration into a reference to it.
128 self.result.refs.push(rf);
129 data.span = rls_data::SpanData {
130 file_name: data.value.clone().into(),
133 line_start: Row::new_one_indexed(1),
134 line_end: Row::new_one_indexed(1),
135 column_start: Column::new_one_indexed(1),
136 column_end: Column::new_one_indexed(1),
139 self.result.defs.push(data);
142 pub fn dump_relation(&mut self, data: Relation) {
143 self.result.relations.push(data);
146 pub fn dump_impl(&mut self, data: Impl) {
147 self.result.impls.push(data);