Skip to content

Commit de17f32

Browse files
committed
---
yaml --- r: 218360 b: refs/heads/master c: 4695fbd h: refs/heads/master v: v3
1 parent f1ed6ed commit de17f32

File tree

7 files changed

+367
-217
lines changed

7 files changed

+367
-217
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 0d60e8d0021a8d3c8214bb0462e03020d3742cfb
2+
refs/heads/master: 4695fbde2157d1a172cea5df99bd661c4aa1204a
33
refs/heads/snap-stage3: ba0e1cd8147d452c356aacb29fb87568ca26f111
44
refs/heads/try: b53c0f93eedcdedd4fd89bccc5a3a09d1c5cd23e
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

trunk/src/librustc_trans/save/dump_csv.rs

Lines changed: 81 additions & 185 deletions
Large diffs are not rendered by default.

trunk/src/librustc_trans/save/mod.rs

Lines changed: 229 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ use std::env;
1515
use std::fs::{self, File};
1616
use std::path::{Path, PathBuf};
1717

18+
use rustc::ast_map::NodeItem;
19+
1820
use syntax::{attr};
1921
use syntax::ast::{self, NodeId, DefId};
2022
use syntax::ast_util;
@@ -61,6 +63,10 @@ pub enum Data {
6163
VariableRefData(VariableRefData),
6264
/// Data for a reference to a type or trait.
6365
TypeRefData(TypeRefData),
66+
/// Data about a function call.
67+
FunctionCallData(FunctionCallData),
68+
/// Data about a method call.
69+
MethodCallData(MethodCallData),
6470
}
6571

6672
/// Data for all kinds of functions and methods.
@@ -120,7 +126,7 @@ pub struct ImplData {
120126
}
121127

122128
/// Data for the use of some item (e.g., the use of a local variable, which
123-
/// will refere to that variables declaration (by ref_id)).
129+
/// will refer to that variables declaration (by ref_id)).
124130
#[derive(Debug)]
125131
pub struct VariableRefData {
126132
pub name: String,
@@ -137,6 +143,24 @@ pub struct TypeRefData {
137143
pub ref_id: DefId,
138144
}
139145

146+
/// Data about a function call.
147+
#[derive(Debug)]
148+
pub struct FunctionCallData {
149+
pub span: Span,
150+
pub scope: NodeId,
151+
pub ref_id: DefId,
152+
}
153+
154+
/// Data about a method call.
155+
#[derive(Debug)]
156+
pub struct MethodCallData {
157+
pub span: Span,
158+
pub scope: NodeId,
159+
pub ref_id: Option<DefId>,
160+
pub decl_id: Option<DefId>,
161+
}
162+
163+
140164

141165
impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
142166
pub fn new(tcx: &'l ty::ctxt<'tcx>,
@@ -172,7 +196,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
172196
qualname: qualname,
173197
declaration: None,
174198
span: sub_span.unwrap(),
175-
scope: self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0),
199+
scope: self.enclosing_scope(item.id),
176200
})
177201
}
178202
ast::ItemStatic(ref typ, mt, ref expr) => {
@@ -191,7 +215,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
191215
name: get_ident(item.ident).to_string(),
192216
qualname: qualname,
193217
span: sub_span.unwrap(),
194-
scope: self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0),
218+
scope: self.enclosing_scope(item.id),
195219
value: value,
196220
type_value: ty_to_string(&typ),
197221
})
@@ -205,7 +229,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
205229
name: get_ident(item.ident).to_string(),
206230
qualname: qualname,
207231
span: sub_span.unwrap(),
208-
scope: self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0),
232+
scope: self.enclosing_scope(item.id),
209233
value: self.span_utils.snippet(expr.span),
210234
type_value: ty_to_string(&typ),
211235
})
@@ -223,7 +247,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
223247
name: get_ident(item.ident).to_string(),
224248
qualname: qualname,
225249
span: sub_span.unwrap(),
226-
scope: self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0),
250+
scope: self.enclosing_scope(item.id),
227251
filename: filename,
228252
})
229253
},
@@ -237,14 +261,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
237261
value: val,
238262
span: sub_span.unwrap(),
239263
qualname: enum_name,
240-
scope: self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0),
264+
scope: self.enclosing_scope(item.id),
241265
})
242266
},
243267
ast::ItemImpl(_, _, _, ref trait_ref, ref typ, _) => {
244268
let mut type_data = None;
245269
let sub_span;
246270

247-
let parent = self.tcx.map.get_enclosing_scope(item.id).unwrap_or(0);
271+
let parent = self.enclosing_scope(item.id);
248272

249273
match typ.node {
250274
// Common case impl for a struct or something basic.
@@ -281,34 +305,114 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
281305
}
282306
}
283307

284-
// FIXME: we ought to be able to get the parent id ourselves, but we can't
285-
// for now.
286-
pub fn get_field_data(&self, field: &ast::StructField, parent: NodeId) -> Option<Data> {
308+
pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option<VariableData> {
287309
match field.node.kind {
288310
ast::NamedField(ident, _) => {
289311
let name = get_ident(ident);
290312
let qualname = format!("::{}::{}",
291-
self.tcx.map.path_to_string(parent),
313+
self.tcx.map.path_to_string(scope),
292314
name);
293315
let typ = self.tcx.node_types().get(&field.node.id).unwrap()
294316
.to_string();
295317
let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon);
296-
Some(Data::VariableData(VariableData {
318+
Some(VariableData {
297319
id: field.node.id,
298320
name: get_ident(ident).to_string(),
299321
qualname: qualname,
300322
span: sub_span.unwrap(),
301-
scope: parent,
323+
scope: scope,
302324
value: "".to_owned(),
303325
type_value: typ,
304-
}))
326+
})
305327
},
306328
_ => None,
307329
}
308330
}
309331

310-
// FIXME: we ought to be able to get the parent id ourselves, but we can't
311-
// for now.
332+
// FIXME would be nice to take a MethodItem here, but the ast provides both
333+
// trait and impl flavours, so the caller must do the disassembly.
334+
pub fn get_method_data(&self,
335+
id: ast::NodeId,
336+
name: ast::Name,
337+
span: Span) -> FunctionData {
338+
// The qualname for a method is the trait name or name of the struct in an impl in
339+
// which the method is declared in, followed by the method's name.
340+
let qualname = match self.tcx.impl_of_method(ast_util::local_def(id)) {
341+
Some(impl_id) => match self.tcx.map.get(impl_id.node) {
342+
NodeItem(item) => {
343+
match item.node {
344+
ast::ItemImpl(_, _, _, _, ref ty, _) => {
345+
let mut result = String::from("<");
346+
result.push_str(&ty_to_string(&**ty));
347+
348+
match self.tcx.trait_of_item(ast_util::local_def(id)) {
349+
Some(def_id) => {
350+
result.push_str(" as ");
351+
result.push_str(
352+
&self.tcx.item_path_str(def_id));
353+
},
354+
None => {}
355+
}
356+
result.push_str(">");
357+
result
358+
}
359+
_ => {
360+
self.tcx.sess.span_bug(span,
361+
&format!("Container {} for method {} not an impl?",
362+
impl_id.node, id));
363+
},
364+
}
365+
},
366+
_ => {
367+
self.tcx.sess.span_bug(span,
368+
&format!("Container {} for method {} is not a node item {:?}",
369+
impl_id.node, id, self.tcx.map.get(impl_id.node)));
370+
},
371+
},
372+
None => match self.tcx.trait_of_item(ast_util::local_def(id)) {
373+
Some(def_id) => {
374+
match self.tcx.map.get(def_id.node) {
375+
NodeItem(_) => {
376+
format!("::{}", self.tcx.item_path_str(def_id))
377+
}
378+
_ => {
379+
self.tcx.sess.span_bug(span,
380+
&format!("Could not find container {} for method {}",
381+
def_id.node, id));
382+
}
383+
}
384+
},
385+
None => {
386+
self.tcx.sess.span_bug(span,
387+
&format!("Could not find container for method {}", id));
388+
},
389+
},
390+
};
391+
392+
let qualname = format!("{}::{}", qualname, &token::get_name(name));
393+
394+
let decl_id = self.tcx.trait_item_of_item(ast_util::local_def(id))
395+
.and_then(|new_id| {
396+
let def_id = new_id.def_id();
397+
if def_id.node != 0 && def_id != ast_util::local_def(id) {
398+
Some(def_id)
399+
} else {
400+
None
401+
}
402+
});
403+
404+
let sub_span = self.span_utils.sub_span_after_keyword(span, keywords::Fn);
405+
406+
FunctionData {
407+
id: id,
408+
name: token::get_name(name).to_string(),
409+
qualname: qualname,
410+
declaration: decl_id,
411+
span: sub_span.unwrap(),
412+
scope: self.enclosing_scope(id),
413+
}
414+
}
415+
312416
pub fn get_trait_ref_data(&self,
313417
trait_ref: &ast::TraitRef,
314418
parent: NodeId)
@@ -337,7 +441,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
337441
return Some(Data::VariableRefData(VariableRefData {
338442
name: get_ident(ident.node).to_string(),
339443
span: sub_span.unwrap(),
340-
scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap_or(0),
444+
scope: self.enclosing_scope(expr.id),
341445
ref_id: f.id,
342446
}));
343447
}
@@ -360,7 +464,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
360464
let sub_span = self.span_utils.span_for_last_ident(path.span);
361465
Some(Data::TypeRefData(TypeRefData {
362466
span: sub_span.unwrap(),
363-
scope: self.tcx.map.get_enclosing_scope(expr.id).unwrap_or(0),
467+
scope: self.enclosing_scope(expr.id),
364468
ref_id: def_id,
365469
}))
366470
}
@@ -372,13 +476,116 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
372476
}
373477
}
374478
}
479+
ast::ExprMethodCall(..) => {
480+
let method_call = ty::MethodCall::expr(expr.id);
481+
let method_id = self.tcx.tables.borrow().method_map[&method_call].def_id;
482+
let (def_id, decl_id) = match self.tcx.impl_or_trait_item(method_id).container() {
483+
ty::ImplContainer(_) => (Some(method_id), None),
484+
ty::TraitContainer(_) => (None, Some(method_id))
485+
};
486+
let sub_span = self.span_utils.sub_span_for_meth_name(expr.span);
487+
let parent = self.enclosing_scope(expr.id);
488+
Some(Data::MethodCallData(MethodCallData {
489+
span: sub_span.unwrap(),
490+
scope: parent,
491+
ref_id: def_id,
492+
decl_id: decl_id,
493+
}))
494+
}
495+
ast::ExprPath(_, ref path) => {
496+
Some(self.get_path_data(expr.id, path))
497+
}
375498
_ => {
376499
// FIXME
377500
unimplemented!();
378501
}
379502
}
380503
}
381504

505+
pub fn get_path_data(&self,
506+
id: NodeId,
507+
path: &ast::Path)
508+
-> Data {
509+
let def_map = self.tcx.def_map.borrow();
510+
if !def_map.contains_key(&id) {
511+
self.tcx.sess.span_bug(path.span,
512+
&format!("def_map has no key for {} in visit_expr", id));
513+
}
514+
let def = def_map.get(&id).unwrap().full_def();
515+
let sub_span = self.span_utils.span_for_last_ident(path.span);
516+
match def {
517+
def::DefUpvar(..) |
518+
def::DefLocal(..) |
519+
def::DefStatic(..) |
520+
def::DefConst(..) |
521+
def::DefAssociatedConst(..) |
522+
def::DefVariant(..) => {
523+
Data::VariableRefData(VariableRefData {
524+
name: self.span_utils.snippet(sub_span.unwrap()),
525+
span: sub_span.unwrap(),
526+
scope: self.enclosing_scope(id),
527+
ref_id: def.def_id(),
528+
})
529+
}
530+
def::DefStruct(def_id) | def::DefTy(def_id, _) => {
531+
Data::TypeRefData(TypeRefData {
532+
span: sub_span.unwrap(),
533+
ref_id: def_id,
534+
scope: self.enclosing_scope(id),
535+
})
536+
}
537+
def::DefMethod(decl_id, provenence) => {
538+
let sub_span = self.span_utils.sub_span_for_meth_name(path.span);
539+
let def_id = if decl_id.krate == ast::LOCAL_CRATE {
540+
let ti = self.tcx.impl_or_trait_item(decl_id);
541+
match provenence {
542+
def::FromTrait(def_id) => {
543+
Some(self.tcx.trait_items(def_id)
544+
.iter()
545+
.find(|mr| {
546+
mr.name() == ti.name()
547+
})
548+
.unwrap()
549+
.def_id())
550+
}
551+
def::FromImpl(def_id) => {
552+
let impl_items = self.tcx.impl_items.borrow();
553+
Some(impl_items.get(&def_id)
554+
.unwrap()
555+
.iter()
556+
.find(|mr| {
557+
self.tcx.impl_or_trait_item(mr.def_id()).name()
558+
== ti.name()
559+
})
560+
.unwrap()
561+
.def_id())
562+
}
563+
}
564+
} else {
565+
None
566+
};
567+
Data::MethodCallData(MethodCallData {
568+
span: sub_span.unwrap(),
569+
scope: self.enclosing_scope(id),
570+
ref_id: def_id,
571+
decl_id: Some(decl_id),
572+
})
573+
},
574+
def::DefFn(def_id, _) => {
575+
Data::FunctionCallData(FunctionCallData {
576+
ref_id: def_id,
577+
span: sub_span.unwrap(),
578+
scope: self.enclosing_scope(id),
579+
})
580+
}
581+
_ => self.tcx.sess.span_bug(path.span,
582+
&format!("Unexpected def kind while looking \
583+
up path in `{}`: `{:?}`",
584+
self.span_utils.snippet(path.span),
585+
def)),
586+
}
587+
}
588+
382589
pub fn get_field_ref_data(&self,
383590
field_ref: &ast::Field,
384591
struct_id: DefId,
@@ -420,6 +627,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
420627
}
421628
}
422629

630+
#[inline]
631+
fn enclosing_scope(&self, id: NodeId) -> NodeId {
632+
self.tcx.map.get_enclosing_scope(id).unwrap_or(0)
633+
}
423634
}
424635

425636
// An AST visitor for collecting paths from patterns.

0 commit comments

Comments
 (0)