From eb4fbda1f2893fe6ec0f917722b3bc853704794c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 25 Jul 2019 12:24:48 -0400 Subject: [PATCH 1/2] 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 dfdf560d41906..fed0764ba9aff 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 82b78369e1339..c1437a27e5d22 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), - } - } -} -impl Drop for JsonDumper { - fn drop(&mut self) { - self.output.dump(&self.result); + pub fn to_output(self, f: impl FnOnce(&Analysis)) { + f(&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 c987a46b56737..edaf4c7df67b6 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)) } } From 68c0ba284d3729a02392d7379673fb196c4a3711 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 25 Jul 2019 12:26:28 -0400 Subject: [PATCH 2/2] Rename JsonDumper to Dumper The Dumper no longer has anything to do specifically with JSON, it merely represents processing into an `Analysis` output. --- src/librustc_save_analysis/dump_visitor.rs | 8 ++++---- .../{json_dumper.rs => dumper.rs} | 10 +++++----- src/librustc_save_analysis/lib.rs | 12 ++++++------ 3 files changed, 15 insertions(+), 15 deletions(-) rename src/librustc_save_analysis/{json_dumper.rs => dumper.rs} (95%) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index fed0764ba9aff..2b349613dc54f 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -10,7 +10,7 @@ //! //! SpanUtils is used to manipulate spans. In particular, to extract sub-spans //! from spans (e.g., the span for `bar` from the above example path). -//! DumpVisitor walks the AST and processes it, and JsonDumper is used for +//! DumpVisitor walks the AST and processes it, and Dumper is used for //! recording the output. use rustc::hir::def::{Res, DefKind as HirDefKind}; @@ -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, JsonDumper}; +use crate::dumper::{Access, Dumper}; use crate::span_utils::SpanUtils; use crate::sig; @@ -78,7 +78,7 @@ macro_rules! access_from_vis { pub struct DumpVisitor<'l, 'tcx, 'll> { save_ctxt: SaveContext<'l, 'tcx>, tcx: TyCtxt<'tcx>, - dumper: &'ll mut JsonDumper, + dumper: &'ll mut Dumper, span: SpanUtils<'l>, @@ -95,7 +95,7 @@ pub struct DumpVisitor<'l, 'tcx, 'll> { impl<'l, 'tcx, 'll> DumpVisitor<'l, 'tcx, 'll> { pub fn new( save_ctxt: SaveContext<'l, 'tcx>, - dumper: &'ll mut JsonDumper, + dumper: &'ll mut Dumper, ) -> DumpVisitor<'l, 'tcx, 'll> { let span_utils = SpanUtils::new(&save_ctxt.tcx.sess); DumpVisitor { diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/dumper.rs similarity index 95% rename from src/librustc_save_analysis/json_dumper.rs rename to src/librustc_save_analysis/dumper.rs index c1437a27e5d22..6fb55e6c99055 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/dumper.rs @@ -9,14 +9,14 @@ pub struct Access { pub public: bool, } -pub struct JsonDumper { +pub struct Dumper { result: Analysis, config: Config, } -impl JsonDumper { - pub fn new(config: Config) -> JsonDumper { - JsonDumper { +impl Dumper { + pub fn new(config: Config) -> Dumper { + Dumper { config: config.clone(), result: Analysis::new(config), } @@ -27,7 +27,7 @@ impl JsonDumper { } } -impl JsonDumper { +impl Dumper { 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 edaf4c7df67b6..ade5e2eca60ba 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -7,7 +7,7 @@ #![recursion_limit="256"] -mod json_dumper; +mod dumper; mod dump_visitor; #[macro_use] mod span_utils; @@ -39,7 +39,7 @@ use syntax::visit::{self, Visitor}; use syntax::print::pprust::{arg_to_string, ty_to_string}; use syntax_pos::*; -use json_dumper::JsonDumper; +use dumper::Dumper; use dump_visitor::DumpVisitor; use span_utils::SpanUtils; @@ -1076,7 +1076,7 @@ impl<'a> SaveHandler for DumpHandler<'a> { ) { let sess = &save_ctxt.tcx.sess; let (output, file_name) = self.output_file(&save_ctxt); - let mut dumper = JsonDumper::new(save_ctxt.config.clone()); + let mut dumper = Dumper::new(save_ctxt.config.clone()); let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); visitor.dump_crate_info(cratename, krate); @@ -1109,12 +1109,12 @@ impl<'b> SaveHandler for CallbackHandler<'b> { cratename: &str, input: &'l Input, ) { - // We're using the JsonDumper here because it has the format of the + // We're using the Dumper here because it has the format of the // save-analysis results that we will pass to the callback. IOW, we are - // using the JsonDumper to collect the save-analysis results, but not + // using the Dumper 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::new(save_ctxt.config.clone()); + let mut dumper = Dumper::new(save_ctxt.config.clone()); let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper); visitor.dump_crate_info(cratename, krate);