Skip to content

Commit 83c6a12

Browse files
committed
save-analysis: start factoring out an API
1 parent c8ddb0f commit 83c6a12

File tree

3 files changed

+129
-69
lines changed

3 files changed

+129
-69
lines changed

src/librustc_trans/save/dump_csv.rs

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
8989
sess: sess,
9090
err_count: Cell::new(0)
9191
}),
92-
cur_scope: 0
92+
cur_scope: 0
9393
}
9494
}
9595

@@ -108,7 +108,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
108108

109109
// Dump info about all the external crates referenced from this crate.
110110
for c in &self.save_ctxt.get_external_crates() {
111-
self.fmt.external_crate_str(krate.span, &c.name, c.number);
111+
self.fmt.external_crate_str(krate.span, &c.name, c.number);
112112
}
113113
self.fmt.recorder.record("end_external_crates\n");
114114
}
@@ -496,58 +496,52 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
496496
decl: &ast::FnDecl,
497497
ty_params: &ast::Generics,
498498
body: &ast::Block) {
499-
let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
499+
let fn_data = self.save_ctxt.get_item_data(item);
500+
if let super::Data::FunctionData(fn_data) = fn_data {
501+
self.fmt.fn_str(item.span,
502+
Some(fn_data.span),
503+
fn_data.id,
504+
&fn_data.qualname,
505+
fn_data.scope);
500506

501-
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Fn);
502-
self.fmt.fn_str(item.span,
503-
sub_span,
504-
item.id,
505-
&qualname[..],
506-
self.cur_scope);
507507

508-
self.process_formals(&decl.inputs, &qualname[..]);
508+
self.process_formals(&decl.inputs, &fn_data.qualname);
509+
self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id);
510+
} else {
511+
unreachable!();
512+
}
509513

510-
// walk arg and return types
511514
for arg in &decl.inputs {
512-
self.visit_ty(&*arg.ty);
515+
self.visit_ty(&arg.ty);
513516
}
514517

515518
if let ast::Return(ref ret_ty) = decl.output {
516-
self.visit_ty(&**ret_ty);
519+
self.visit_ty(&ret_ty);
517520
}
518521

519-
// walk the body
520-
self.nest(item.id, |v| v.visit_block(&*body));
521-
522-
self.process_generic_params(ty_params, item.span, &qualname[..], item.id);
522+
self.nest(item.id, |v| v.visit_block(&body));
523523
}
524524

525-
fn process_static(&mut self,
526-
item: &ast::Item,
527-
typ: &ast::Ty,
528-
mt: ast::Mutability,
529-
expr: &ast::Expr)
525+
fn process_static_or_const_item(&mut self,
526+
item: &ast::Item,
527+
typ: &ast::Ty,
528+
expr: &ast::Expr)
530529
{
531-
let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
532-
533-
// If the variable is immutable, save the initialising expression.
534-
let (value, keyword) = match mt {
535-
ast::MutMutable => (String::from_str("<mutable>"), keywords::Mut),
536-
ast::MutImmutable => (self.span.snippet(expr.span), keywords::Static),
537-
};
538-
539-
let sub_span = self.span.sub_span_after_keyword(item.span, keyword);
540-
self.fmt.static_str(item.span,
541-
sub_span,
542-
item.id,
543-
&get_ident(item.ident),
544-
&qualname[..],
545-
&value[..],
546-
&ty_to_string(&*typ),
547-
self.cur_scope);
530+
let var_data = self.save_ctxt.get_item_data(item);
531+
if let super::Data::VariableData(var_data) = var_data {
532+
self.fmt.static_str(item.span,
533+
Some(var_data.span),
534+
var_data.id,
535+
&var_data.name,
536+
&var_data.qualname,
537+
&var_data.value,
538+
&var_data.type_value,
539+
var_data.scope);
540+
} else {
541+
unreachable!();
542+
}
548543

549-
// walk type and init value
550-
self.visit_ty(&*typ);
544+
self.visit_ty(&typ);
551545
self.visit_expr(expr);
552546
}
553547

@@ -562,12 +556,13 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
562556

563557
let sub_span = self.span.sub_span_after_keyword(span,
564558
keywords::Const);
559+
565560
self.fmt.static_str(span,
566561
sub_span,
567562
id,
568563
&get_ident((*ident).clone()),
569564
&qualname[..],
570-
"",
565+
&self.span.snippet(expr.span),
571566
&ty_to_string(&*typ),
572567
self.cur_scope);
573568

@@ -1174,10 +1169,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
11741169
}
11751170
ast::ItemFn(ref decl, _, _, ref ty_params, ref body) =>
11761171
self.process_fn(item, &**decl, ty_params, &**body),
1177-
ast::ItemStatic(ref typ, mt, ref expr) =>
1178-
self.process_static(item, &**typ, mt, &**expr),
1172+
ast::ItemStatic(ref typ, _, ref expr) =>
1173+
self.process_static_or_const_item(item, typ, expr),
11791174
ast::ItemConst(ref typ, ref expr) =>
1180-
self.process_const(item.id, &item.ident, item.span, &*typ, &*expr),
1175+
self.process_static_or_const_item(item, &typ, &expr),
11811176
ast::ItemStruct(ref def, ref ty_params) => self.process_struct(item, &**def, ty_params),
11821177
ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
11831178
ast::ItemImpl(_, _,
@@ -1378,7 +1373,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
13781373
},
13791374
_ => {
13801375
visit::walk_expr(self, ex)
1381-
},
1376+
}
13821377
}
13831378
}
13841379

@@ -1401,7 +1396,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
14011396
// This is to get around borrow checking, because we need mut self to call process_path.
14021397
let mut paths_to_process = vec![];
14031398
// process collected paths
1404-
for &(id, ref p, ref immut, ref_kind) in &collector.collected_paths {
1399+
for &(id, ref p, immut, ref_kind) in &collector.collected_paths {
14051400
let def_map = self.analysis.ty_cx.def_map.borrow();
14061401
if !def_map.contains_key(&id) {
14071402
self.sess.span_bug(p.span,
@@ -1411,7 +1406,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
14111406
let def = def_map.get(&id).unwrap().full_def();
14121407
match def {
14131408
def::DefLocal(id) => {
1414-
let value = if *immut {
1409+
let value = if immut == ast::MutImmutable {
14151410
self.span.snippet(p.span).to_string()
14161411
} else {
14171412
"<mutable>".to_string()
@@ -1464,8 +1459,12 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
14641459

14651460
let value = self.span.snippet(l.span);
14661461

1467-
for &(id, ref p, ref immut, _) in &collector.collected_paths {
1468-
let value = if *immut { value.to_string() } else { "<mutable>".to_string() };
1462+
for &(id, ref p, immut, _) in &collector.collected_paths {
1463+
let value = if immut == ast::MutImmutable {
1464+
value.to_string()
1465+
} else {
1466+
"<mutable>".to_string()
1467+
};
14691468
let types = self.analysis.ty_cx.node_types();
14701469
let typ = ppaux::ty_to_string(&self.analysis.ty_cx, *types.get(&id).unwrap());
14711470
// Get the span only for the name of the variable (I hope the path

src/librustc_trans/save/mod.rs

Lines changed: 77 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ use syntax::{attr};
1919
use syntax::ast::{self, NodeId, DefId};
2020
use syntax::ast_util;
2121
use syntax::codemap::*;
22-
use syntax::parse::token::keywords;
22+
use syntax::parse::token::{self, get_ident, keywords};
2323
use syntax::visit::{self, Visitor};
24+
use syntax::print::pprust::ty_to_string;
25+
2426

2527
use self::span_utils::SpanUtils;
2628

@@ -40,18 +42,32 @@ pub struct CrateData {
4042
pub number: u32,
4143
}
4244

45+
// Data for any entity in the Rust language. The actual data contained varied
46+
// with the kind of entity being queried. See the nested structs for details.
4347
pub enum Data {
4448
FunctionData(FunctionData),
49+
VariableData(VariableData),
4550
}
4651

4752
pub struct FunctionData {
4853
pub id: NodeId,
54+
pub name: String,
4955
pub qualname: String,
5056
pub declaration: Option<DefId>,
5157
pub span: Span,
5258
pub scope: NodeId,
5359
}
5460

61+
pub struct VariableData {
62+
pub id: NodeId,
63+
pub name: String,
64+
pub qualname: String,
65+
pub span: Span,
66+
pub scope: NodeId,
67+
pub value: String,
68+
pub type_value: String,
69+
}
70+
5571
impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
5672
pub fn new(sess: &'l Session,
5773
analysis: &'l ty::CrateAnalysis<'tcx>,
@@ -78,35 +94,71 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
7894
pub fn get_item_data(&self, item: &ast::Item) -> Data {
7995
match item.node {
8096
ast::Item_::ItemFn(..) => {
81-
let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
97+
let name = self.analysis.ty_cx.map.path_to_string(item.id);
98+
let qualname = format!("::{}", name);
8299
let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn);
83100

84101
Data::FunctionData(FunctionData {
85102
id: item.id,
103+
name: name,
86104
qualname: qualname,
87105
declaration: None,
88106
span: sub_span.unwrap(),
89107
scope: self.analysis.ty_cx.map.get_parent(item.id),
90108
})
91109
}
110+
ast::ItemStatic(ref typ, mt, ref expr) => {
111+
let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
112+
113+
// If the variable is immutable, save the initialising expression.
114+
let value = match mt {
115+
ast::MutMutable => String::from_str("<mutable>"),
116+
ast::MutImmutable => self.span_utils.snippet(expr.span),
117+
};
118+
119+
let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Static);
120+
121+
Data::VariableData(VariableData {
122+
id: item.id,
123+
name: get_ident(item.ident).to_string(),
124+
qualname: qualname,
125+
span: sub_span.unwrap(),
126+
scope: self.analysis.ty_cx.map.get_parent(item.id),
127+
value: value,
128+
type_value: ty_to_string(&typ),
129+
})
130+
}
131+
ast::ItemConst(ref typ, ref expr) => {
132+
let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
133+
let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Const);
134+
135+
Data::VariableData(VariableData {
136+
id: item.id,
137+
name: get_ident(item.ident).to_string(),
138+
qualname: qualname,
139+
span: sub_span.unwrap(),
140+
scope: self.analysis.ty_cx.map.get_parent(item.id),
141+
value: self.span_utils.snippet(expr.span),
142+
type_value: ty_to_string(&typ),
143+
})
144+
}
92145
_ => {
146+
// FIXME
93147
unimplemented!();
94148
}
95149
}
96150
}
97151

98-
pub fn get_data_for_id(&self, id: &NodeId) -> Data {
99-
// TODO
100-
unimplemented!();
152+
pub fn get_data_for_id(&self, _id: &NodeId) -> Data {
153+
// FIXME
154+
unimplemented!();
101155
}
102156
}
103157

104158
// An AST visitor for collecting paths from patterns.
105159
struct PathCollector {
106-
// TODO bool -> ast::mutable
107-
// TODO recorder -> var kind new enum
108-
// The Row field identifies the kind of formal variable.
109-
collected_paths: Vec<(NodeId, ast::Path, bool, recorder::Row)>,
160+
// The Row field identifies the kind of pattern.
161+
collected_paths: Vec<(NodeId, ast::Path, ast::Mutability, recorder::Row)>,
110162
}
111163

112164
impl PathCollector {
@@ -119,29 +171,35 @@ impl PathCollector {
119171

120172
impl<'v> Visitor<'v> for PathCollector {
121173
fn visit_pat(&mut self, p: &ast::Pat) {
174+
if generated_code(p.span) {
175+
return;
176+
}
177+
122178
match p.node {
123179
ast::PatStruct(ref path, _, _) => {
124-
self.collected_paths.push((p.id, path.clone(), false, recorder::StructRef));
180+
self.collected_paths.push((p.id,
181+
path.clone(),
182+
ast::MutMutable,
183+
recorder::StructRef));
125184
}
126185
ast::PatEnum(ref path, _) |
127186
ast::PatQPath(_, ref path) => {
128-
self.collected_paths.push((p.id, path.clone(), false, recorder::VarRef));
187+
self.collected_paths.push((p.id, path.clone(), ast::MutMutable, recorder::VarRef));
129188
}
130189
ast::PatIdent(bm, ref path1, _) => {
190+
debug!("PathCollector, visit ident in pat {}: {:?} {:?}",
191+
token::get_ident(path1.node),
192+
p.span,
193+
path1.span);
131194
let immut = match bm {
132195
// Even if the ref is mut, you can't change the ref, only
133196
// the data pointed at, so showing the initialising expression
134197
// is still worthwhile.
135-
ast::BindByRef(_) => true,
136-
ast::BindByValue(mt) => {
137-
match mt {
138-
ast::MutMutable => false,
139-
ast::MutImmutable => true,
140-
}
141-
}
198+
ast::BindByRef(_) => ast::MutImmutable,
199+
ast::BindByValue(mt) => mt,
142200
};
143201
// collect path for either visit_local or visit_arm
144-
let path = ast_util::ident_to_path(path1.span,path1.node);
202+
let path = ast_util::ident_to_path(path1.span, path1.node);
145203
self.collected_paths.push((p.id, path, immut, recorder::VarRef));
146204
}
147205
_ => {}

src/librustc_trans/save/recorder.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ macro_rules! svec {
6262
})
6363
}
6464

65+
// FIXME recorder should operate on super::Data, rather than lots of ad hoc
66+
// data.
67+
6568
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
6669
pub enum Row {
6770
Variable,

0 commit comments

Comments
 (0)