3 use rls_data::config::Config;
4 use rls_data::{self, Analysis, CompilationOptions, CratePreludeData, Def, DefKind, Impl, Import,
5 MacroRef, Ref, RefKind, Relation};
6 use rls_span::{Column, Row};
16 pub struct JsonDumper<O: DumpOutput> {
22 pub trait DumpOutput {
23 fn dump(&mut self, result: &Analysis);
26 pub struct WriteOutput<'b, W: Write> {
30 impl<'b, W: Write> DumpOutput for WriteOutput<'b, W> {
31 fn dump(&mut self, result: &Analysis) {
32 if let Err(e) = serde_json::to_writer(self.output.by_ref(), result) {
33 error!("Can't serialize save-analysis: {:?}", e);
38 pub struct CallbackOutput<'b> {
39 callback: &'b mut dyn FnMut(&Analysis),
42 impl<'b> DumpOutput for CallbackOutput<'b> {
43 fn dump(&mut self, result: &Analysis) {
44 (self.callback)(result)
48 impl<'b, W: Write> JsonDumper<WriteOutput<'b, W>> {
49 pub fn new(writer: &'b mut W, config: Config) -> JsonDumper<WriteOutput<'b, W>> {
51 output: WriteOutput { output: writer },
52 config: config.clone(),
53 result: Analysis::new(config),
58 impl<'b> JsonDumper<CallbackOutput<'b>> {
60 callback: &'b mut dyn FnMut(&Analysis),
62 ) -> JsonDumper<CallbackOutput<'b>> {
64 output: CallbackOutput { callback },
65 config: config.clone(),
66 result: Analysis::new(config),
71 impl<O: DumpOutput> Drop for JsonDumper<O> {
73 self.output.dump(&self.result);
77 impl<'b, O: DumpOutput + 'b> JsonDumper<O> {
78 pub fn crate_prelude(&mut self, data: CratePreludeData) {
79 self.result.prelude = Some(data)
82 pub fn compilation_opts(&mut self, data: CompilationOptions) {
83 self.result.compilation = Some(data);
86 pub fn _macro_use(&mut self, data: MacroRef) {
87 if self.config.pub_only || self.config.reachable_only {
90 self.result.macro_refs.push(data);
93 pub fn import(&mut self, access: &Access, import: Import) {
94 if !access.public && self.config.pub_only
95 || !access.reachable && self.config.reachable_only {
98 self.result.imports.push(import);
101 pub fn dump_ref(&mut self, data: Ref) {
102 if self.config.pub_only || self.config.reachable_only {
105 self.result.refs.push(data);
108 pub fn dump_def(&mut self, access: &Access, mut data: Def) {
109 if !access.public && self.config.pub_only
110 || !access.reachable && self.config.reachable_only {
113 if data.kind == DefKind::Mod && data.span.file_name.to_str().unwrap() != data.value {
114 // If the module is an out-of-line definition, then we'll make the
115 // definition the first character in the module's file and turn
116 // the declaration into a reference to it.
122 self.result.refs.push(rf);
123 data.span = rls_data::SpanData {
124 file_name: data.value.clone().into(),
127 line_start: Row::new_one_indexed(1),
128 line_end: Row::new_one_indexed(1),
129 column_start: Column::new_one_indexed(1),
130 column_end: Column::new_one_indexed(1),
133 self.result.defs.push(data);
136 pub fn dump_relation(&mut self, data: Relation) {
137 self.result.relations.push(data);
140 pub fn dump_impl(&mut self, data: Impl) {
141 self.result.impls.push(data);