Skip to content

Commit 0c766cb

Browse files
committed
save-analysis: API-ify methods
1 parent df5a1ca commit 0c766cb

File tree

2 files changed

+116
-94
lines changed

2 files changed

+116
-94
lines changed

src/librustc_trans/save/dump_csv.rs

Lines changed: 26 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,11 @@ 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));
311+
let method_data = self.save_ctxt.get_method_data(id, name, span);
369312

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-
});
380-
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,
@@ -1087,8 +1017,11 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
10871017
trait_item.span, &*ty, &*expr);
10881018
}
10891019
ast::MethodTraitItem(ref sig, ref body) => {
1090-
self.process_method(sig, body.as_ref().map(|x| &**x),
1091-
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);
10921025
}
10931026
ast::ConstTraitItem(_, None) |
10941027
ast::TypeTraitItem(..) => {}
@@ -1102,8 +1035,11 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
11021035
impl_item.span, &ty, &expr);
11031036
}
11041037
ast::MethodImplItem(ref sig, ref body) => {
1105-
self.process_method(sig, Some(body), impl_item.id,
1106-
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);
11071043
}
11081044
ast::TypeImplItem(_) |
11091045
ast::MacImplItem(_) => {}

src/librustc_trans/save/mod.rs

Lines changed: 90 additions & 4 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;
@@ -227,7 +229,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
227229
name: get_ident(item.ident).to_string(),
228230
qualname: qualname,
229231
span: sub_span.unwrap(),
230-
scope: selfenclosing_scope(item.id),
232+
scope: self.enclosing_scope(item.id),
231233
value: self.span_utils.snippet(expr.span),
232234
type_value: ty_to_string(&typ),
233235
})
@@ -303,7 +305,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
303305
}
304306
}
305307

306-
pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option<Data> {
308+
pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option<VariableData> {
307309
match field.node.kind {
308310
ast::NamedField(ident, _) => {
309311
let name = get_ident(ident);
@@ -313,20 +315,104 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
313315
let typ = self.tcx.node_types().get(&field.node.id).unwrap()
314316
.to_string();
315317
let sub_span = self.span_utils.sub_span_before_token(field.span, token::Colon);
316-
Some(Data::VariableData(VariableData {
318+
Some(VariableData {
317319
id: field.node.id,
318320
name: get_ident(ident).to_string(),
319321
qualname: qualname,
320322
span: sub_span.unwrap(),
321323
scope: scope,
322324
value: "".to_owned(),
323325
type_value: typ,
324-
}))
326+
})
325327
},
326328
_ => None,
327329
}
328330
}
329331

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+
330416
pub fn get_trait_ref_data(&self,
331417
trait_ref: &ast::TraitRef,
332418
parent: NodeId)

0 commit comments

Comments
 (0)