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