From eb4fbda1f2893fe6ec0f917722b3bc853704794c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 25 Jul 2019 12:24:48 -0400 Subject: [PATCH] Simplify save-analysis JSON dumper interface --- src/librustc_save_analysis/dump_visitor.rs | 18 +++---- src/librustc_save_analysis/json_dumper.rs | 59 +++------------------- src/librustc_save_analysis/lib.rs | 24 +++++---- 3 files changed, 29 insertions(+), 72 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index dfdf560d419..fed0764ba9a 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -38,7 +38,7 @@ use syntax_pos::*; use crate::{escape, generated_code, id_from_def_id, id_from_node_id, lower_attributes, PathCollector, SaveContext}; -use crate::json_dumper::{Access, DumpOutput, JsonDumper}; +use crate::json_dumper::{Access, JsonDumper}; use crate::span_utils::SpanUtils; use crate::sig; @@ -75,10 +75,10 @@ macro_rules! access_from_vis { }; } -pub struct DumpVisitor<'l, 'tcx, 'll, O: DumpOutput> { +pub struct DumpVisitor<'l, 'tcx, 'll> { save_ctxt: SaveContext<'l, 'tcx>, tcx: TyCtxt<'tcx>, - dumper: &'ll mut JsonDumper, + dumper: &'ll mut JsonDumper, span: SpanUtils<'l>, @@ -92,11 +92,11 @@ pub struct DumpVisitor<'l, 'tcx, 'll, O: DumpOutput> { // macro_calls: FxHashSet, } -impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { +impl<'l, 'tcx, 'll> DumpVisitor<'l, 'tcx, 'll> { pub fn new( save_ctxt: SaveContext<'l, 'tcx>, - dumper: &'ll mut JsonDumper, - ) -> DumpVisitor<'l, 'tcx, 'll, O> { + dumper: &'ll mut JsonDumper, + ) -> DumpVisitor<'l, 'tcx, 'll> { let span_utils = SpanUtils::new(&save_ctxt.tcx.sess); DumpVisitor { tcx: save_ctxt.tcx, @@ -111,7 +111,7 @@ impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn nest_scope(&mut self, scope_id: NodeId, f: F) where - F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, O>), + F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll>), { let parent_scope = self.cur_scope; self.cur_scope = scope_id; @@ -121,7 +121,7 @@ impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn nest_tables(&mut self, item_id: NodeId, f: F) where - F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, O>), + F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll>), { let item_def_id = self.tcx.hir().local_def_id_from_node_id(item_id); if self.tcx.has_typeck_tables(item_def_id) { @@ -1311,7 +1311,7 @@ impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { } } -impl<'l, 'tcx, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll, O> { +impl<'l, 'tcx, 'll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll> { fn visit_mod(&mut self, m: &'l ast::Mod, span: Span, attrs: &[ast::Attribute], id: NodeId) { // Since we handle explicit modules ourselves in visit_item, this should // only get called for the root module of a crate. diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index 82b78369e13..c1437a27e5d 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -1,80 +1,33 @@ -use std::io::Write; - use rls_data::config::Config; use rls_data::{self, Analysis, CompilationOptions, CratePreludeData, Def, DefKind, Impl, Import, MacroRef, Ref, RefKind, Relation}; use rls_span::{Column, Row}; -use log::error; - #[derive(Debug)] pub struct Access { pub reachable: bool, pub public: bool, } -pub struct JsonDumper { +pub struct JsonDumper { result: Analysis, config: Config, - output: O, } -pub trait DumpOutput { - fn dump(&mut self, result: &Analysis); -} - -pub struct WriteOutput<'b, W: Write> { - output: &'b mut W, -} - -impl<'b, W: Write> DumpOutput for WriteOutput<'b, W> { - fn dump(&mut self, result: &Analysis) { - if let Err(e) = serde_json::to_writer(self.output.by_ref(), result) { - error!("Can't serialize save-analysis: {:?}", e); - } - } -} - -pub struct CallbackOutput<'b> { - callback: &'b mut dyn FnMut(&Analysis), -} - -impl<'b> DumpOutput for CallbackOutput<'b> { - fn dump(&mut self, result: &Analysis) { - (self.callback)(result) - } -} - -impl<'b, W: Write> JsonDumper> { - pub fn new(writer: &'b mut W, config: Config) -> JsonDumper> { +impl JsonDumper { + pub fn new(config: Config) -> JsonDumper { JsonDumper { - output: WriteOutput { output: writer }, config: config.clone(), result: Analysis::new(config), } } -} -impl<'b> JsonDumper> { - pub fn with_callback( - callback: &'b mut dyn FnMut(&Analysis), - config: Config, - ) -> JsonDumper> { - JsonDumper { - output: CallbackOutput { callback }, - config: config.clone(), - result: Analysis::new(config), - } + pub fn to_output(self, f: impl FnOnce(&Analysis)) { + f(&self.result) } } -impl Drop for JsonDumper { - fn drop(&mut self) { - self.output.dump(&self.result); - } -} - -impl<'b, O: DumpOutput + 'b> JsonDumper { +impl JsonDumper { pub fn crate_prelude(&mut self, data: CratePreludeData) { self.result.prelude = Some(data) } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index c987a46b567..edaf4c7df67 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -1075,17 +1075,19 @@ impl<'a> SaveHandler for DumpHandler<'a> { input: &'l Input, ) { let sess = &save_ctxt.tcx.sess; - let file_name = { - let (mut output, file_name) = self.output_file(&save_ctxt); - let mut dumper = JsonDumper::new(&mut output, save_ctxt.config.clone()); - let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); + let (output, file_name) = self.output_file(&save_ctxt); + let mut dumper = JsonDumper::new(save_ctxt.config.clone()); + let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); - visitor.dump_crate_info(cratename, krate); - visitor.dump_compilation_options(input, cratename); - visit::walk_crate(&mut visitor, krate); + visitor.dump_crate_info(cratename, krate); + visitor.dump_compilation_options(input, cratename); + visit::walk_crate(&mut visitor, krate); - file_name - }; + dumper.to_output(|analysis| { + if let Err(e) = serde_json::to_writer(output, analysis) { + error!("Can't serialize save-analysis: {:?}", e); + } + }); if sess.opts.debugging_opts.emit_artifact_notifications { sess.parse_sess.span_diagnostic @@ -1112,12 +1114,14 @@ impl<'b> SaveHandler for CallbackHandler<'b> { // using the JsonDumper to collect the save-analysis results, but not // actually to dump them to a file. This is all a bit convoluted and // there is certainly a simpler design here trying to get out (FIXME). - let mut dumper = JsonDumper::with_callback(self.callback, save_ctxt.config.clone()); + let mut dumper = JsonDumper::new(save_ctxt.config.clone()); let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); visitor.dump_crate_info(cratename, krate); visitor.dump_compilation_options(input, cratename); visit::walk_crate(&mut visitor, krate); + + dumper.to_output(|a| (self.callback)(a)) } }