Skip to content

Commit 409297f

Browse files
committed
allow filtering analysis by reachability
1 parent d08a164 commit 409297f

File tree

2 files changed

+119
-44
lines changed

2 files changed

+119
-44
lines changed

src/librustc_save_analysis/dump_visitor.rs

+103-36
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use syntax::codemap::Spanned;
4242
use syntax_pos::*;
4343

4444
use {escape, generated_code, lower_attributes, PathCollector, SaveContext};
45-
use json_dumper::{DumpOutput, JsonDumper};
45+
use json_dumper::{Access, DumpOutput, JsonDumper};
4646
use span_utils::SpanUtils;
4747
use sig;
4848

@@ -341,7 +341,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
341341
let span = self.span_from_span(sub_span.expect("No span found for variable"));
342342

343343
self.dumper.dump_def(
344-
false,
344+
&Access {
345+
public: false,
346+
reachable: false,
347+
},
345348
Def {
346349
kind: DefKind::Local,
347350
id,
@@ -387,8 +390,12 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
387390

388391
method_data.value = sig_str;
389392
method_data.sig = sig::method_signature(id, name, generics, sig, &self.save_ctxt);
390-
self.dumper
391-
.dump_def(vis == ast::Visibility::Public, method_data);
393+
self.dumper.dump_def(
394+
&Access {
395+
public: vis == ast::Visibility::Public,
396+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(id),
397+
},
398+
method_data);
392399
}
393400

394401
// walk arg and return types
@@ -409,8 +416,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
409416
fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) {
410417
let field_data = self.save_ctxt.get_field_data(field, parent_id);
411418
if let Some(field_data) = field_data {
412-
self.dumper
413-
.dump_def(field.vis == ast::Visibility::Public, field_data);
419+
self.dumper.dump_def(
420+
&Access {
421+
public: field.vis == ast::Visibility::Public,
422+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(field.id),
423+
},
424+
field_data,
425+
);
414426
}
415427
}
416428

@@ -432,7 +444,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
432444
let span = self.span_from_span(param_ss);
433445

434446
self.dumper.dump_def(
435-
false,
447+
&Access {
448+
public: false,
449+
reachable: false,
450+
},
436451
Def {
437452
kind: DefKind::Type,
438453
id,
@@ -467,8 +482,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
467482
|v| v.process_formals(&decl.inputs, &fn_data.qualname),
468483
);
469484
self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id);
470-
self.dumper
471-
.dump_def(item.vis == ast::Visibility::Public, fn_data);
485+
self.dumper.dump_def(
486+
&Access {
487+
public: item.vis == ast::Visibility::Public,
488+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(item.id),
489+
},
490+
fn_data,
491+
);
472492
}
473493

474494
for arg in &decl.inputs {
@@ -491,8 +511,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
491511
self.nest_tables(item.id, |v| {
492512
if let Some(var_data) = v.save_ctxt.get_item_data(item) {
493513
down_cast_data!(var_data, DefData, item.span);
494-
v.dumper
495-
.dump_def(item.vis == ast::Visibility::Public, var_data);
514+
v.dumper.dump_def(
515+
&Access {
516+
public: item.vis == ast::Visibility::Public,
517+
reachable: v.save_ctxt.analysis.access_levels.is_reachable(item.id),
518+
},
519+
var_data,
520+
);
496521
}
497522
v.visit_ty(&typ);
498523
v.visit_expr(expr);
@@ -516,14 +541,16 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
516541

517542
if !self.span.filter_generated(sub_span, span) {
518543
let sig = sig::assoc_const_signature(id, name, typ, expr, &self.save_ctxt);
519-
let id = ::id_from_node_id(id, &self.save_ctxt);
520544
let span = self.span_from_span(sub_span.expect("No span found for variable"));
521545

522546
self.dumper.dump_def(
523-
vis == ast::Visibility::Public,
547+
&Access {
548+
public: vis == ast::Visibility::Public,
549+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(id),
550+
},
524551
Def {
525552
kind: DefKind::Const,
526-
id,
553+
id: ::id_from_node_id(id, &self.save_ctxt),
527554
span,
528555
name: name.to_string(),
529556
qualname,
@@ -596,7 +623,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
596623
if !self.span.filter_generated(sub_span, item.span) {
597624
let span = self.span_from_span(sub_span.expect("No span found for struct"));
598625
self.dumper.dump_def(
599-
item.vis == ast::Visibility::Public,
626+
&Access {
627+
public: item.vis == ast::Visibility::Public,
628+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(item.id),
629+
},
600630
Def {
601631
kind,
602632
id: ::id_from_node_id(item.id, &self.save_ctxt),
@@ -635,6 +665,11 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
635665
};
636666
down_cast_data!(enum_data, DefData, item.span);
637667

668+
let access = Access {
669+
public: item.vis == ast::Visibility::Public,
670+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(item.id),
671+
};
672+
638673
for variant in &enum_definition.variants {
639674
let name = variant.node.name.name.to_string();
640675
let mut qualname = enum_data.qualname.clone();
@@ -660,7 +695,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
660695
let parent = Some(::id_from_node_id(item.id, &self.save_ctxt));
661696

662697
self.dumper.dump_def(
663-
item.vis == ast::Visibility::Public,
698+
&access,
664699
Def {
665700
kind: DefKind::StructVariant,
666701
id,
@@ -700,7 +735,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
700735
let parent = Some(::id_from_node_id(item.id, &self.save_ctxt));
701736

702737
self.dumper.dump_def(
703-
item.vis == ast::Visibility::Public,
738+
&access,
704739
Def {
705740
kind: DefKind::TupleVariant,
706741
id,
@@ -730,8 +765,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
730765
}
731766
}
732767
self.process_generic_params(ty_params, item.span, &enum_data.qualname, item.id);
733-
self.dumper
734-
.dump_def(item.vis == ast::Visibility::Public, enum_data);
768+
self.dumper.dump_def(&access, enum_data);
735769
}
736770

737771
fn process_impl(
@@ -783,7 +817,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
783817
.map(|i| ::id_from_node_id(i.id, &self.save_ctxt))
784818
.collect();
785819
self.dumper.dump_def(
786-
item.vis == ast::Visibility::Public,
820+
&Access {
821+
public: item.vis == ast::Visibility::Public,
822+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(item.id),
823+
},
787824
Def {
788825
kind: DefKind::Trait,
789826
id,
@@ -846,8 +883,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
846883
fn process_mod(&mut self, item: &ast::Item) {
847884
if let Some(mod_data) = self.save_ctxt.get_item_data(item) {
848885
down_cast_data!(mod_data, DefData, item.span);
849-
self.dumper
850-
.dump_def(item.vis == ast::Visibility::Public, mod_data);
886+
self.dumper.dump_def(
887+
&Access {
888+
public: item.vis == ast::Visibility::Public,
889+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(item.id),
890+
},
891+
mod_data,
892+
);
851893
}
852894
}
853895

@@ -1038,7 +1080,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
10381080
let span = self.span_from_span(sub_span.expect("No span found for variable"));
10391081

10401082
self.dumper.dump_def(
1041-
false,
1083+
&Access {
1084+
public: false,
1085+
reachable: false,
1086+
},
10421087
Def {
10431088
kind: DefKind::Local,
10441089
id,
@@ -1138,7 +1183,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
11381183
let id = ::id_from_node_id(trait_item.id, &self.save_ctxt);
11391184

11401185
self.dumper.dump_def(
1141-
true,
1186+
&Access {
1187+
public: true,
1188+
reachable: true,
1189+
},
11421190
Def {
11431191
kind: DefKind::Type,
11441192
id,
@@ -1225,7 +1273,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
12251273
let span = self.span_from_span(span);
12261274

12271275
self.dumper.dump_def(
1228-
true,
1276+
&Access {
1277+
public: true,
1278+
reachable: true,
1279+
},
12291280
Def {
12301281
kind: DefKind::Mod,
12311282
id: data_id,
@@ -1249,6 +1300,11 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
12491300
self.process_macro_use(item.span);
12501301
match item.node {
12511302
Use(ref use_item) => {
1303+
let access = Access {
1304+
public: item.vis == ast::Visibility::Public,
1305+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(item.id),
1306+
};
1307+
12521308
match use_item.node {
12531309
ast::ViewPathSimple(ident, ref path) => {
12541310
let sub_span = self.span.span_for_last_ident(path.span);
@@ -1273,7 +1329,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
12731329
let span =
12741330
self.span_from_span(sub_span.expect("No span found for use"));
12751331
self.dumper.import(
1276-
item.vis == ast::Visibility::Public,
1332+
&access,
12771333
Import {
12781334
kind: ImportKind::Use,
12791335
ref_id: mod_id.map(|id| ::id_from_def_id(id)),
@@ -1302,7 +1358,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
13021358
let span =
13031359
self.span_from_span(sub_span.expect("No span found for use glob"));
13041360
self.dumper.import(
1305-
item.vis == ast::Visibility::Public,
1361+
&access,
13061362
Import {
13071363
kind: ImportKind::GlobUse,
13081364
ref_id: None,
@@ -1334,7 +1390,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
13341390
let span =
13351391
self.span_from_span(alias_span.expect("No span found for extern crate"));
13361392
self.dumper.import(
1337-
false,
1393+
&Access {
1394+
public: false,
1395+
reachable: false,
1396+
},
13381397
Import {
13391398
kind: ImportKind::ExternCrate,
13401399
ref_id: None,
@@ -1373,7 +1432,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
13731432
let id = ::id_from_node_id(item.id, &self.save_ctxt);
13741433

13751434
self.dumper.dump_def(
1376-
item.vis == ast::Visibility::Public,
1435+
&Access {
1436+
public: item.vis == ast::Visibility::Public,
1437+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(item.id),
1438+
},
13771439
Def {
13781440
kind: DefKind::Type,
13791441
id,
@@ -1596,7 +1658,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
15961658
let span = self.span_from_span(sp);
15971659

15981660
self.dumper.dump_def(
1599-
false,
1661+
&Access {
1662+
public: false,
1663+
reachable: false,
1664+
},
16001665
Def {
16011666
kind: DefKind::Local,
16021667
id,
@@ -1662,6 +1727,11 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
16621727
}
16631728

16641729
fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) {
1730+
let access = Access {
1731+
public: item.vis == ast::Visibility::Public,
1732+
reachable: self.save_ctxt.analysis.access_levels.is_reachable(item.id),
1733+
};
1734+
16651735
match item.node {
16661736
ast::ForeignItemKind::Fn(ref decl, ref generics) => {
16671737
if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) {
@@ -1672,8 +1742,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
16721742
|v| v.process_formals(&decl.inputs, &fn_data.qualname),
16731743
);
16741744
self.process_generic_params(generics, item.span, &fn_data.qualname, item.id);
1675-
self.dumper
1676-
.dump_def(item.vis == ast::Visibility::Public, fn_data);
1745+
self.dumper.dump_def(&access, fn_data);
16771746
}
16781747

16791748
for arg in &decl.inputs {
@@ -1687,17 +1756,15 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
16871756
ast::ForeignItemKind::Static(ref ty, _) => {
16881757
if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) {
16891758
down_cast_data!(var_data, DefData, item.span);
1690-
self.dumper
1691-
.dump_def(item.vis == ast::Visibility::Public, var_data);
1759+
self.dumper.dump_def(&access, var_data);
16921760
}
16931761

16941762
self.visit_ty(ty);
16951763
}
16961764
ast::ForeignItemKind::Ty => {
16971765
if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) {
16981766
down_cast_data!(var_data, DefData, item.span);
1699-
self.dumper
1700-
.dump_def(item.vis == ast::Visibility::Public, var_data);
1767+
self.dumper.dump_def(&access, var_data);
17011768
}
17021769
}
17031770
}

src/librustc_save_analysis/json_dumper.rs

+16-8
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ use rls_data::{self, Analysis, CratePreludeData, Def, DefKind, Import, MacroRef,
1717
use rls_data::config::Config;
1818
use rls_span::{Column, Row};
1919

20+
#[derive(Debug)]
21+
pub struct Access {
22+
pub reachable: bool,
23+
pub public: bool,
24+
}
25+
2026
pub struct JsonDumper<O: DumpOutput> {
2127
result: Analysis,
2228
config: Config,
@@ -84,33 +90,35 @@ impl<'b, O: DumpOutput + 'b> JsonDumper<O> {
8490
}
8591

8692
pub fn macro_use(&mut self, data: MacroRef) {
87-
if self.config.pub_only {
93+
if self.config.pub_only || self.config.reachable_only {
8894
return;
8995
}
9096
self.result.macro_refs.push(data);
9197
}
9298

93-
pub fn import(&mut self, public: bool, import: Import) {
94-
if !public && self.config.pub_only {
99+
pub fn import(&mut self, access: &Access, import: Import) {
100+
if !access.public && self.config.pub_only
101+
|| !access.reachable && self.config.reachable_only {
95102
return;
96103
}
97104
self.result.imports.push(import);
98105
}
99106

100107
pub fn dump_ref(&mut self, data: Ref) {
101-
if self.config.pub_only {
108+
if self.config.pub_only || self.config.reachable_only {
102109
return;
103110
}
104111
self.result.refs.push(data);
105112
}
106113

107-
pub fn dump_def(&mut self, public: bool, mut data: Def) {
108-
if !public && self.config.pub_only {
114+
pub fn dump_def(&mut self, access: &Access, mut data: Def) {
115+
if !access.public && self.config.pub_only
116+
|| !access.reachable && self.config.reachable_only {
109117
return;
110118
}
111119
if data.kind == DefKind::Mod && data.span.file_name.to_str().unwrap() != data.value {
112-
// If the module is an out-of-line defintion, then we'll make the
113-
// definition the first character in the module's file and turn the
120+
// If the module is an out-of-line definition, then we'll make the
121+
// definition the first character in the module's file and turn
114122
// the declaration into a reference to it.
115123
let rf = Ref {
116124
kind: RefKind::Mod,

0 commit comments

Comments
 (0)