]>
Commit | Line | Data |
---|---|---|
a7813a04 XL |
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. | |
4 | // | |
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. | |
10 | ||
11 | use std::io::Write; | |
12 | ||
a7813a04 XL |
13 | use rustc_serialize::json::as_json; |
14 | ||
abe05a73 XL |
15 | use rls_data::{self, Analysis, CratePreludeData, Def, DefKind, Import, MacroRef, Ref, RefKind, |
16 | Relation}; | |
3b2f2976 | 17 | use rls_data::config::Config; |
cc61c64b XL |
18 | use rls_span::{Column, Row}; |
19 | ||
cc61c64b | 20 | pub struct JsonDumper<O: DumpOutput> { |
a7813a04 | 21 | result: Analysis, |
3b2f2976 | 22 | config: Config, |
cc61c64b | 23 | output: O, |
a7813a04 XL |
24 | } |
25 | ||
cc61c64b XL |
26 | pub trait DumpOutput { |
27 | fn dump(&mut self, result: &Analysis); | |
a7813a04 XL |
28 | } |
29 | ||
cc61c64b XL |
30 | pub struct WriteOutput<'b, W: Write + 'b> { |
31 | output: &'b mut W, | |
32 | } | |
33 | ||
34 | impl<'b, W: Write> DumpOutput for WriteOutput<'b, W> { | |
35 | fn dump(&mut self, result: &Analysis) { | |
36 | if let Err(_) = write!(self.output, "{}", as_json(&result)) { | |
a7813a04 XL |
37 | error!("Error writing output"); |
38 | } | |
39 | } | |
40 | } | |
41 | ||
cc61c64b XL |
42 | pub struct CallbackOutput<'b> { |
43 | callback: &'b mut FnMut(&Analysis), | |
44 | } | |
45 | ||
46 | impl<'b> DumpOutput for CallbackOutput<'b> { | |
47 | fn dump(&mut self, result: &Analysis) { | |
48 | (self.callback)(result) | |
49 | } | |
50 | } | |
51 | ||
52 | impl<'b, W: Write> JsonDumper<WriteOutput<'b, W>> { | |
3b2f2976 XL |
53 | pub fn new(writer: &'b mut W, config: Config) -> JsonDumper<WriteOutput<'b, W>> { |
54 | JsonDumper { | |
55 | output: WriteOutput { output: writer }, | |
56 | config: config.clone(), | |
abe05a73 | 57 | result: Analysis::new(config), |
3b2f2976 | 58 | } |
cc61c64b XL |
59 | } |
60 | } | |
61 | ||
62 | impl<'b> JsonDumper<CallbackOutput<'b>> { | |
abe05a73 XL |
63 | pub fn with_callback( |
64 | callback: &'b mut FnMut(&Analysis), | |
65 | config: Config, | |
66 | ) -> JsonDumper<CallbackOutput<'b>> { | |
3b2f2976 XL |
67 | JsonDumper { |
68 | output: CallbackOutput { callback: callback }, | |
69 | config: config.clone(), | |
70 | result: Analysis::new(config), | |
71 | } | |
cc61c64b XL |
72 | } |
73 | } | |
74 | ||
75 | impl<O: DumpOutput> Drop for JsonDumper<O> { | |
76 | fn drop(&mut self) { | |
77 | self.output.dump(&self.result); | |
78 | } | |
79 | } | |
80 | ||
3b2f2976 XL |
81 | impl<'b, O: DumpOutput + 'b> JsonDumper<O> { |
82 | pub fn crate_prelude(&mut self, data: CratePreludeData) { | |
a7813a04 XL |
83 | self.result.prelude = Some(data) |
84 | } | |
85 | ||
3b2f2976 XL |
86 | pub fn macro_use(&mut self, data: MacroRef) { |
87 | if self.config.pub_only { | |
88 | return; | |
89 | } | |
041b39d2 XL |
90 | self.result.macro_refs.push(data); |
91 | } | |
a7813a04 | 92 | |
3b2f2976 XL |
93 | pub fn import(&mut self, public: bool, import: Import) { |
94 | if !public && self.config.pub_only { | |
95 | return; | |
96 | } | |
041b39d2 XL |
97 | self.result.imports.push(import); |
98 | } | |
a7813a04 | 99 | |
3b2f2976 XL |
100 | pub fn dump_ref(&mut self, data: Ref) { |
101 | if self.config.pub_only { | |
102 | return; | |
103 | } | |
041b39d2 XL |
104 | self.result.refs.push(data); |
105 | } | |
3b2f2976 XL |
106 | |
107 | pub fn dump_def(&mut self, public: bool, mut data: Def) { | |
108 | if !public && self.config.pub_only { | |
109 | return; | |
110 | } | |
041b39d2 | 111 | if data.kind == DefKind::Mod && data.span.file_name.to_str().unwrap() != data.value { |
476ff2be | 112 | // If the module is an out-of-line defintion, then we'll make the |
3b2f2976 | 113 | // definition the first character in the module's file and turn the |
476ff2be SL |
114 | // the declaration into a reference to it. |
115 | let rf = Ref { | |
116 | kind: RefKind::Mod, | |
041b39d2 XL |
117 | span: data.span, |
118 | ref_id: data.id, | |
476ff2be SL |
119 | }; |
120 | self.result.refs.push(rf); | |
041b39d2 XL |
121 | data.span = rls_data::SpanData { |
122 | file_name: data.value.clone().into(), | |
476ff2be SL |
123 | byte_start: 0, |
124 | byte_end: 0, | |
cc61c64b XL |
125 | line_start: Row::new_one_indexed(1), |
126 | line_end: Row::new_one_indexed(1), | |
127 | column_start: Column::new_one_indexed(1), | |
128 | column_end: Column::new_one_indexed(1), | |
476ff2be SL |
129 | } |
130 | } | |
041b39d2 | 131 | self.result.defs.push(data); |
476ff2be SL |
132 | } |
133 | ||
3b2f2976 | 134 | pub fn dump_relation(&mut self, data: Relation) { |
041b39d2 | 135 | self.result.relations.push(data); |
32a655c1 SL |
136 | } |
137 | } |