Simplify save-analysis JSON dumper interface
This commit is contained in:
parent
eedf6ce4ef
commit
eb4fbda1f2
3 changed files with 29 additions and 72 deletions
|
@ -38,7 +38,7 @@ use syntax_pos::*;
|
||||||
|
|
||||||
use crate::{escape, generated_code, id_from_def_id, id_from_node_id, lower_attributes,
|
use crate::{escape, generated_code, id_from_def_id, id_from_node_id, lower_attributes,
|
||||||
PathCollector, SaveContext};
|
PathCollector, SaveContext};
|
||||||
use crate::json_dumper::{Access, DumpOutput, JsonDumper};
|
use crate::json_dumper::{Access, JsonDumper};
|
||||||
use crate::span_utils::SpanUtils;
|
use crate::span_utils::SpanUtils;
|
||||||
use crate::sig;
|
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>,
|
save_ctxt: SaveContext<'l, 'tcx>,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
dumper: &'ll mut JsonDumper<O>,
|
dumper: &'ll mut JsonDumper,
|
||||||
|
|
||||||
span: SpanUtils<'l>,
|
span: SpanUtils<'l>,
|
||||||
|
|
||||||
|
@ -92,11 +92,11 @@ pub struct DumpVisitor<'l, 'tcx, 'll, O: DumpOutput> {
|
||||||
// macro_calls: FxHashSet<Span>,
|
// macro_calls: FxHashSet<Span>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
impl<'l, 'tcx, 'll> DumpVisitor<'l, 'tcx, 'll> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
save_ctxt: SaveContext<'l, 'tcx>,
|
save_ctxt: SaveContext<'l, 'tcx>,
|
||||||
dumper: &'ll mut JsonDumper<O>,
|
dumper: &'ll mut JsonDumper,
|
||||||
) -> DumpVisitor<'l, 'tcx, 'll, O> {
|
) -> DumpVisitor<'l, 'tcx, 'll> {
|
||||||
let span_utils = SpanUtils::new(&save_ctxt.tcx.sess);
|
let span_utils = SpanUtils::new(&save_ctxt.tcx.sess);
|
||||||
DumpVisitor {
|
DumpVisitor {
|
||||||
tcx: save_ctxt.tcx,
|
tcx: save_ctxt.tcx,
|
||||||
|
@ -111,7 +111,7 @@ impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||||
|
|
||||||
fn nest_scope<F>(&mut self, scope_id: NodeId, f: F)
|
fn nest_scope<F>(&mut self, scope_id: NodeId, f: F)
|
||||||
where
|
where
|
||||||
F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, O>),
|
F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll>),
|
||||||
{
|
{
|
||||||
let parent_scope = self.cur_scope;
|
let parent_scope = self.cur_scope;
|
||||||
self.cur_scope = scope_id;
|
self.cur_scope = scope_id;
|
||||||
|
@ -121,7 +121,7 @@ impl<'l, 'tcx, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
|
||||||
|
|
||||||
fn nest_tables<F>(&mut self, item_id: NodeId, f: F)
|
fn nest_tables<F>(&mut self, item_id: NodeId, f: F)
|
||||||
where
|
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);
|
let item_def_id = self.tcx.hir().local_def_id_from_node_id(item_id);
|
||||||
if self.tcx.has_typeck_tables(item_def_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) {
|
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
|
// Since we handle explicit modules ourselves in visit_item, this should
|
||||||
// only get called for the root module of a crate.
|
// only get called for the root module of a crate.
|
||||||
|
|
|
@ -1,80 +1,33 @@
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
use rls_data::config::Config;
|
use rls_data::config::Config;
|
||||||
use rls_data::{self, Analysis, CompilationOptions, CratePreludeData, Def, DefKind, Impl, Import,
|
use rls_data::{self, Analysis, CompilationOptions, CratePreludeData, Def, DefKind, Impl, Import,
|
||||||
MacroRef, Ref, RefKind, Relation};
|
MacroRef, Ref, RefKind, Relation};
|
||||||
use rls_span::{Column, Row};
|
use rls_span::{Column, Row};
|
||||||
|
|
||||||
use log::error;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Access {
|
pub struct Access {
|
||||||
pub reachable: bool,
|
pub reachable: bool,
|
||||||
pub public: bool,
|
pub public: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct JsonDumper<O: DumpOutput> {
|
pub struct JsonDumper {
|
||||||
result: Analysis,
|
result: Analysis,
|
||||||
config: Config,
|
config: Config,
|
||||||
output: O,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait DumpOutput {
|
impl JsonDumper {
|
||||||
fn dump(&mut self, result: &Analysis);
|
pub fn new(config: Config) -> JsonDumper {
|
||||||
}
|
|
||||||
|
|
||||||
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<WriteOutput<'b, W>> {
|
|
||||||
pub fn new(writer: &'b mut W, config: Config) -> JsonDumper<WriteOutput<'b, W>> {
|
|
||||||
JsonDumper {
|
JsonDumper {
|
||||||
output: WriteOutput { output: writer },
|
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
result: Analysis::new(config),
|
result: Analysis::new(config),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'b> JsonDumper<CallbackOutput<'b>> {
|
pub fn to_output(self, f: impl FnOnce(&Analysis)) {
|
||||||
pub fn with_callback(
|
f(&self.result)
|
||||||
callback: &'b mut dyn FnMut(&Analysis),
|
|
||||||
config: Config,
|
|
||||||
) -> JsonDumper<CallbackOutput<'b>> {
|
|
||||||
JsonDumper {
|
|
||||||
output: CallbackOutput { callback },
|
|
||||||
config: config.clone(),
|
|
||||||
result: Analysis::new(config),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<O: DumpOutput> Drop for JsonDumper<O> {
|
impl JsonDumper {
|
||||||
fn drop(&mut self) {
|
|
||||||
self.output.dump(&self.result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'b, O: DumpOutput + 'b> JsonDumper<O> {
|
|
||||||
pub fn crate_prelude(&mut self, data: CratePreludeData) {
|
pub fn crate_prelude(&mut self, data: CratePreludeData) {
|
||||||
self.result.prelude = Some(data)
|
self.result.prelude = Some(data)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1075,17 +1075,19 @@ impl<'a> SaveHandler for DumpHandler<'a> {
|
||||||
input: &'l Input,
|
input: &'l Input,
|
||||||
) {
|
) {
|
||||||
let sess = &save_ctxt.tcx.sess;
|
let sess = &save_ctxt.tcx.sess;
|
||||||
let file_name = {
|
let (output, file_name) = self.output_file(&save_ctxt);
|
||||||
let (mut output, file_name) = self.output_file(&save_ctxt);
|
let mut dumper = JsonDumper::new(save_ctxt.config.clone());
|
||||||
let mut dumper = JsonDumper::new(&mut output, save_ctxt.config.clone());
|
|
||||||
let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
|
let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
|
||||||
|
|
||||||
visitor.dump_crate_info(cratename, krate);
|
visitor.dump_crate_info(cratename, krate);
|
||||||
visitor.dump_compilation_options(input, cratename);
|
visitor.dump_compilation_options(input, cratename);
|
||||||
visit::walk_crate(&mut visitor, krate);
|
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 {
|
if sess.opts.debugging_opts.emit_artifact_notifications {
|
||||||
sess.parse_sess.span_diagnostic
|
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
|
// 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
|
// 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).
|
// 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);
|
let mut visitor = DumpVisitor::new(save_ctxt, &mut dumper);
|
||||||
|
|
||||||
visitor.dump_crate_info(cratename, krate);
|
visitor.dump_crate_info(cratename, krate);
|
||||||
visitor.dump_compilation_options(input, cratename);
|
visitor.dump_compilation_options(input, cratename);
|
||||||
visit::walk_crate(&mut visitor, krate);
|
visit::walk_crate(&mut visitor, krate);
|
||||||
|
|
||||||
|
dumper.to_output(|a| (self.callback)(a))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue