Skip to content

Commit 736886c

Browse files
committed
Auto merge of #26907 - nrc:save-fns, r=brson
r? @huonw
2 parents 67256df + 0c766cb commit 736886c

File tree

5 files changed

+331
-210
lines changed

5 files changed

+331
-210
lines changed

src/librustc_trans/save/dump_csv.rs

Lines changed: 81 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,17 @@
2828
//! DumpCsvVisitor walks the AST and processes it.
2929
3030

31-
use super::{escape, generated_code, recorder, SaveContext, PathCollector};
31+
use super::{escape, generated_code, recorder, SaveContext, PathCollector, Data};
3232

3333
use session::Session;
3434

3535
use middle::def;
3636
use middle::ty::{self, Ty};
37-
use rustc::ast_map::NodeItem;
3837

3938
use std::cell::Cell;
4039
use std::fs::File;
4140
use std::path::Path;
4241

43-
use syntax::ast_util;
4442
use syntax::ast::{self, NodeId, DefId};
4543
use syntax::codemap::*;
4644
use syntax::parse::token::{self, get_ident, keywords};
@@ -298,101 +296,34 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
298296
}
299297
}
300298

301-
fn process_method(&mut self, sig: &ast::MethodSig,
299+
fn process_method(&mut self,
300+
sig: &ast::MethodSig,
302301
body: Option<&ast::Block>,
303-
id: ast::NodeId, name: ast::Name,
302+
id: ast::NodeId,
303+
name: ast::Name,
304304
span: Span) {
305305
if generated_code(span) {
306306
return;
307307
}
308308

309309
debug!("process_method: {}:{}", id, token::get_name(name));
310310

311-
let scope_id;
312-
// The qualname for a method is the trait name or name of the struct in an impl in
313-
// which the method is declared in, followed by the method's name.
314-
let qualname = match self.tcx.impl_of_method(ast_util::local_def(id)) {
315-
Some(impl_id) => match self.tcx.map.get(impl_id.node) {
316-
NodeItem(item) => {
317-
scope_id = item.id;
318-
match item.node {
319-
ast::ItemImpl(_, _, _, _, ref ty, _) => {
320-
let mut result = String::from("<");
321-
result.push_str(&ty_to_string(&**ty));
322-
323-
match self.tcx.trait_of_item(ast_util::local_def(id)) {
324-
Some(def_id) => {
325-
result.push_str(" as ");
326-
result.push_str(
327-
&self.tcx.item_path_str(def_id));
328-
},
329-
None => {}
330-
}
331-
result.push_str(">");
332-
result
333-
}
334-
_ => {
335-
self.sess.span_bug(span,
336-
&format!("Container {} for method {} not an impl?",
337-
impl_id.node, id));
338-
},
339-
}
340-
},
341-
_ => {
342-
self.sess.span_bug(span,
343-
&format!("Container {} for method {} is not a node item {:?}",
344-
impl_id.node, id, self.tcx.map.get(impl_id.node)));
345-
},
346-
},
347-
None => match self.tcx.trait_of_item(ast_util::local_def(id)) {
348-
Some(def_id) => {
349-
scope_id = def_id.node;
350-
match self.tcx.map.get(def_id.node) {
351-
NodeItem(_) => {
352-
format!("::{}", self.tcx.item_path_str(def_id))
353-
}
354-
_ => {
355-
self.sess.span_bug(span,
356-
&format!("Could not find container {} for method {}",
357-
def_id.node, id));
358-
}
359-
}
360-
},
361-
None => {
362-
self.sess.span_bug(span,
363-
&format!("Could not find container for method {}", id));
364-
},
365-
},
366-
};
367-
368-
let qualname = &format!("{}::{}", qualname, &token::get_name(name));
369-
370-
// record the decl for this def (if it has one)
371-
let decl_id = self.tcx.trait_item_of_item(ast_util::local_def(id))
372-
.and_then(|new_id| {
373-
let def_id = new_id.def_id();
374-
if def_id.node != 0 && def_id != ast_util::local_def(id) {
375-
Some(def_id)
376-
} else {
377-
None
378-
}
379-
});
311+
let method_data = self.save_ctxt.get_method_data(id, name, span);
380312

381-
let sub_span = self.span.sub_span_after_keyword(span, keywords::Fn);
382313
if body.is_some() {
383314
self.fmt.method_str(span,
384-
sub_span,
385-
id,
386-
qualname,
387-
decl_id,
388-
scope_id);
389-
self.process_formals(&sig.decl.inputs, qualname);
315+
Some(method_data.span),
316+
method_data.id,
317+
&method_data.qualname,
318+
method_data.declaration,
319+
method_data.scope);
320+
self.process_formals(&sig.decl.inputs, &method_data.qualname);
390321
} else {
391322
self.fmt.method_decl_str(span,
392-
sub_span,
393-
id,
394-
qualname,
395-
scope_id);
323+
Some(method_data.span),
324+
method_data.id,
325+
&method_data.qualname,
326+
method_data.scope);
396327
}
397328

398329
// walk arg and return types
@@ -411,7 +342,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
411342

412343
self.process_generic_params(&sig.generics,
413344
span,
414-
qualname,
345+
&method_data.qualname,
415346
id);
416347
}
417348

@@ -432,7 +363,6 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
432363
parent_id: NodeId) {
433364
let field_data = self.save_ctxt.get_field_data(field, parent_id);
434365
if let Some(field_data) = field_data {
435-
down_cast_data!(field_data, VariableData, self, field.span);
436366
self.fmt.field_str(field.span,
437367
Some(field_data.span),
438368
field_data.id,
@@ -738,90 +668,51 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
738668

739669
fn process_path(&mut self,
740670
id: NodeId,
741-
span: Span,
742671
path: &ast::Path,
743672
ref_kind: Option<recorder::Row>) {
744-
if generated_code(span) {
745-
return
673+
if generated_code(path.span) {
674+
return;
746675
}
747676

748-
let def_map = self.tcx.def_map.borrow();
749-
if !def_map.contains_key(&id) {
750-
self.sess.span_bug(span,
751-
&format!("def_map has no key for {} in visit_expr", id));
752-
}
753-
let def = def_map.get(&id).unwrap().full_def();
754-
let sub_span = self.span.span_for_last_ident(span);
755-
match def {
756-
def::DefUpvar(..) |
757-
def::DefLocal(..) |
758-
def::DefStatic(..) |
759-
def::DefConst(..) |
760-
def::DefAssociatedConst(..) |
761-
def::DefVariant(..) => self.fmt.ref_str(ref_kind.unwrap_or(recorder::VarRef),
762-
span,
763-
sub_span,
764-
def.def_id(),
765-
self.cur_scope),
766-
def::DefStruct(def_id) => self.fmt.ref_str(recorder::TypeRef,
767-
span,
768-
sub_span,
769-
def_id,
770-
self.cur_scope),
771-
def::DefTy(def_id, _) => self.fmt.ref_str(recorder::TypeRef,
772-
span,
773-
sub_span,
774-
def_id,
775-
self.cur_scope),
776-
def::DefMethod(declid, provenence) => {
777-
let sub_span = self.span.sub_span_for_meth_name(span);
778-
let defid = if declid.krate == ast::LOCAL_CRATE {
779-
let ti = self.tcx.impl_or_trait_item(declid);
780-
match provenence {
781-
def::FromTrait(def_id) => {
782-
Some(self.tcx.trait_items(def_id)
783-
.iter()
784-
.find(|mr| {
785-
mr.name() == ti.name()
786-
})
787-
.unwrap()
788-
.def_id())
789-
}
790-
def::FromImpl(def_id) => {
791-
let impl_items = self.tcx.impl_items.borrow();
792-
Some(impl_items.get(&def_id)
793-
.unwrap()
794-
.iter()
795-
.find(|mr| {
796-
self.tcx.impl_or_trait_item(mr.def_id()).name()
797-
== ti.name()
798-
})
799-
.unwrap()
800-
.def_id())
801-
}
802-
}
803-
} else {
804-
None
805-
};
806-
self.fmt.meth_call_str(span,
807-
sub_span,
808-
defid,
809-
Some(declid),
810-
self.cur_scope);
811-
},
812-
def::DefFn(def_id, _) => {
813-
self.fmt.fn_call_str(span,
814-
sub_span,
815-
def_id,
816-
self.cur_scope)
677+
let path_data = self.save_ctxt.get_path_data(id, path);
678+
match path_data {
679+
Data::VariableRefData(ref vrd) => {
680+
self.fmt.ref_str(ref_kind.unwrap_or(recorder::VarRef),
681+
path.span,
682+
Some(vrd.span),
683+
vrd.ref_id,
684+
vrd.scope);
685+
686+
}
687+
Data::TypeRefData(ref trd) => {
688+
self.fmt.ref_str(recorder::TypeRef,
689+
path.span,
690+
Some(trd.span),
691+
trd.ref_id,
692+
trd.scope);
693+
}
694+
Data::MethodCallData(ref mcd) => {
695+
self.fmt.meth_call_str(path.span,
696+
Some(mcd.span),
697+
mcd.ref_id,
698+
mcd.decl_id,
699+
mcd.scope);
700+
}
701+
Data::FunctionCallData(fcd) => {
702+
self.fmt.fn_call_str(path.span,
703+
Some(fcd.span),
704+
fcd.ref_id,
705+
fcd.scope);
706+
}
707+
_ => {
708+
self.sess.span_bug(path.span,
709+
&format!("Unexpected data: {:?}", path_data));
817710
}
818-
_ => self.sess.span_bug(span,
819-
&format!("Unexpected def kind while looking \
820-
up path in `{}`: `{:?}`",
821-
self.span.snippet(span),
822-
def)),
823711
}
824-
// modules or types in the path prefix
712+
713+
// Modules or types in the path prefix.
714+
let def_map = self.tcx.def_map.borrow();
715+
let def = def_map.get(&id).unwrap().full_def();
825716
match def {
826717
def::DefMethod(did, _) => {
827718
let ti = self.tcx.impl_or_trait_item(did);
@@ -861,6 +752,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
861752
struct_lit_data.ref_id,
862753
struct_lit_data.scope);
863754
let struct_def = struct_lit_data.ref_id;
755+
let scope = self.save_ctxt.enclosing_scope(ex.id);
864756

865757
for field in fields {
866758
if generated_code(field.ident.span) {
@@ -869,7 +761,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
869761

870762
let field_data = self.save_ctxt.get_field_ref_data(field,
871763
struct_def,
872-
self.cur_scope);
764+
scope);
873765
self.fmt.ref_str(recorder::VarRef,
874766
field.ident.span,
875767
Some(field_data.span),
@@ -886,18 +778,14 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
886778
fn process_method_call(&mut self,
887779
ex: &ast::Expr,
888780
args: &Vec<P<ast::Expr>>) {
889-
let method_call = ty::MethodCall::expr(ex.id);
890-
let method_id = self.tcx.tables.borrow().method_map[&method_call].def_id;
891-
let (def_id, decl_id) = match self.tcx.impl_or_trait_item(method_id).container() {
892-
ty::ImplContainer(_) => (Some(method_id), None),
893-
ty::TraitContainer(_) => (None, Some(method_id))
894-
};
895-
let sub_span = self.span.sub_span_for_meth_name(ex.span);
896-
self.fmt.meth_call_str(ex.span,
897-
sub_span,
898-
def_id,
899-
decl_id,
900-
self.cur_scope);
781+
if let Some(call_data) = self.save_ctxt.get_expr_data(ex) {
782+
down_cast_data!(call_data, MethodCallData, self, ex.span);
783+
self.fmt.meth_call_str(ex.span,
784+
Some(call_data.span),
785+
call_data.ref_id,
786+
call_data.decl_id,
787+
call_data.scope);
788+
}
901789

902790
// walk receiver and args
903791
visit::walk_exprs(self, &args);
@@ -1129,8 +1017,11 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
11291017
trait_item.span, &*ty, &*expr);
11301018
}
11311019
ast::MethodTraitItem(ref sig, ref body) => {
1132-
self.process_method(sig, body.as_ref().map(|x| &**x),
1133-
trait_item.id, trait_item.ident.name, trait_item.span);
1020+
self.process_method(sig,
1021+
body.as_ref().map(|x| &**x),
1022+
trait_item.id,
1023+
trait_item.ident.name,
1024+
trait_item.span);
11341025
}
11351026
ast::ConstTraitItem(_, None) |
11361027
ast::TypeTraitItem(..) => {}
@@ -1144,8 +1035,11 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
11441035
impl_item.span, &ty, &expr);
11451036
}
11461037
ast::MethodImplItem(ref sig, ref body) => {
1147-
self.process_method(sig, Some(body), impl_item.id,
1148-
impl_item.ident.name, impl_item.span);
1038+
self.process_method(sig,
1039+
Some(body),
1040+
impl_item.id,
1041+
impl_item.ident.name,
1042+
impl_item.span);
11491043
}
11501044
ast::TypeImplItem(_) |
11511045
ast::MacImplItem(_) => {}
@@ -1191,7 +1085,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
11911085
visit::walk_expr(self, ex);
11921086
}
11931087
ast::ExprPath(_, ref path) => {
1194-
self.process_path(ex.id, path.span, path, None);
1088+
self.process_path(ex.id, path, None);
11951089
visit::walk_expr(self, ex);
11961090
}
11971091
ast::ExprStruct(ref path, ref fields, ref base) =>
@@ -1287,6 +1181,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
12871181

12881182
// This is to get around borrow checking, because we need mut self to call process_path.
12891183
let mut paths_to_process = vec![];
1184+
12901185
// process collected paths
12911186
for &(id, ref p, immut, ref_kind) in &collector.collected_paths {
12921187
let def_map = self.tcx.def_map.borrow();
@@ -1323,11 +1218,12 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
13231218
def)
13241219
}
13251220
}
1221+
13261222
for &(id, ref path, ref_kind) in &paths_to_process {
1327-
self.process_path(id, path.span, path, ref_kind);
1223+
self.process_path(id, path, ref_kind);
13281224
}
13291225
visit::walk_expr_opt(self, &arm.guard);
1330-
self.visit_expr(&*arm.body);
1226+
self.visit_expr(&arm.body);
13311227
}
13321228

13331229
fn visit_stmt(&mut self, s: &ast::Stmt) {

0 commit comments

Comments
 (0)