Auto merge of #25783 - nrc:save-api-2, r=@huonw
A little more work on the save-analysis API. r? @huonw
This commit is contained in:
commit
448ce12bc1
|
@ -508,7 +508,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
|||
self.process_formals(&decl.inputs, &fn_data.qualname);
|
||||
self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id);
|
||||
} else {
|
||||
unreachable!();
|
||||
self.sess.span_bug(item.span, "expected FunctionData");
|
||||
}
|
||||
|
||||
for arg in &decl.inputs {
|
||||
|
@ -538,7 +538,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
|||
&var_data.type_value,
|
||||
var_data.scope);
|
||||
} else {
|
||||
unreachable!();
|
||||
self.sess.span_bug(item.span, "expected VariableData");
|
||||
}
|
||||
|
||||
self.visit_ty(&typ);
|
||||
|
@ -768,22 +768,18 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
|||
}
|
||||
|
||||
fn process_mod(&mut self,
|
||||
item: &ast::Item, // The module in question, represented as an item.
|
||||
m: &ast::Mod) {
|
||||
let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
|
||||
|
||||
let cm = self.sess.codemap();
|
||||
let filename = cm.span_to_filename(m.inner);
|
||||
|
||||
let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Mod);
|
||||
self.fmt.mod_str(item.span,
|
||||
sub_span,
|
||||
item.id,
|
||||
&qualname[..],
|
||||
self.cur_scope,
|
||||
&filename[..]);
|
||||
|
||||
self.nest(item.id, |v| visit::walk_mod(v, m));
|
||||
item: &ast::Item) { // The module in question, represented as an item.
|
||||
let mod_data = self.save_ctxt.get_item_data(item);
|
||||
if let super::Data::ModData(mod_data) = mod_data {
|
||||
self.fmt.mod_str(item.span,
|
||||
Some(mod_data.span),
|
||||
mod_data.id,
|
||||
&mod_data.qualname,
|
||||
mod_data.scope,
|
||||
&mod_data.filename);
|
||||
} else {
|
||||
self.sess.span_bug(item.span, "expected ModData");
|
||||
}
|
||||
}
|
||||
|
||||
fn process_path(&mut self,
|
||||
|
@ -1188,7 +1184,10 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
|
|||
}
|
||||
ast::ItemTrait(_, ref generics, ref trait_refs, ref methods) =>
|
||||
self.process_trait(item, generics, trait_refs, methods),
|
||||
ast::ItemMod(ref m) => self.process_mod(item, m),
|
||||
ast::ItemMod(ref m) => {
|
||||
self.process_mod(item);
|
||||
self.nest(item.id, |v| visit::walk_mod(v, m));
|
||||
}
|
||||
ast::ItemTy(ref ty, ref ty_params) => {
|
||||
let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
|
||||
let value = ty_to_string(&**ty);
|
||||
|
@ -1295,30 +1294,22 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DumpCsvVisitor<'l, 'tcx> {
|
|||
ast::ExprStruct(ref path, ref fields, ref base) =>
|
||||
self.process_struct_lit(ex, path, fields, base),
|
||||
ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args),
|
||||
ast::ExprField(ref sub_ex, ident) => {
|
||||
ast::ExprField(ref sub_ex, _) => {
|
||||
if generated_code(sub_ex.span) {
|
||||
return
|
||||
}
|
||||
|
||||
self.visit_expr(&**sub_ex);
|
||||
let ty = &ty::expr_ty_adjusted(&self.analysis.ty_cx, &**sub_ex).sty;
|
||||
match *ty {
|
||||
ty::ty_struct(def_id, _) => {
|
||||
let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id);
|
||||
for f in &fields {
|
||||
if f.name == ident.node.name {
|
||||
let sub_span = self.span.span_for_last_ident(ex.span);
|
||||
self.fmt.ref_str(recorder::VarRef,
|
||||
ex.span,
|
||||
sub_span,
|
||||
f.id,
|
||||
self.cur_scope);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => self.sess.span_bug(ex.span,
|
||||
&format!("Expected struct type, found {:?}", ty)),
|
||||
self.visit_expr(&sub_ex);
|
||||
|
||||
let field_data = self.save_ctxt.get_expr_data(ex);
|
||||
if let super::Data::VariableRefData(field_data) = field_data {
|
||||
self.fmt.ref_str(recorder::VarRef,
|
||||
ex.span,
|
||||
Some(field_data.span),
|
||||
field_data.ref_id,
|
||||
field_data.scope);
|
||||
} else {
|
||||
self.sess.span_bug(ex.span, "expected VariableRefData");
|
||||
}
|
||||
},
|
||||
ast::ExprTupField(ref sub_ex, idx) => {
|
||||
|
|
|
@ -49,6 +49,12 @@ pub enum Data {
|
|||
FunctionData(FunctionData),
|
||||
/// Data for local and global variables (consts and statics).
|
||||
VariableData(VariableData),
|
||||
/// Data for modules.
|
||||
ModData(ModData),
|
||||
|
||||
/// Data for the use of some variable (e.g., the use of a local variable, which
|
||||
/// will refere to that variables declaration).
|
||||
VariableRefData(VariableRefData),
|
||||
}
|
||||
|
||||
/// Data for all kinds of functions and methods.
|
||||
|
@ -72,6 +78,26 @@ pub struct VariableData {
|
|||
pub type_value: String,
|
||||
}
|
||||
|
||||
/// Data for modules.
|
||||
pub struct ModData {
|
||||
pub id: NodeId,
|
||||
pub name: String,
|
||||
pub qualname: String,
|
||||
pub span: Span,
|
||||
pub scope: NodeId,
|
||||
pub filename: String,
|
||||
}
|
||||
|
||||
/// Data for the use of some item (e.g., the use of a local variable, which
|
||||
/// will refere to that variables declaration (by ref_id)).
|
||||
pub struct VariableRefData {
|
||||
pub name: String,
|
||||
pub span: Span,
|
||||
pub scope: NodeId,
|
||||
pub ref_id: DefId,
|
||||
}
|
||||
|
||||
|
||||
impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||
pub fn new(sess: &'l Session,
|
||||
analysis: &'l ty::CrateAnalysis<'tcx>,
|
||||
|
@ -97,7 +123,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
|
||||
pub fn get_item_data(&self, item: &ast::Item) -> Data {
|
||||
match item.node {
|
||||
ast::Item_::ItemFn(..) => {
|
||||
ast::ItemFn(..) => {
|
||||
let name = self.analysis.ty_cx.map.path_to_string(item.id);
|
||||
let qualname = format!("::{}", name);
|
||||
let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Fn);
|
||||
|
@ -146,6 +172,58 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
|||
type_value: ty_to_string(&typ),
|
||||
})
|
||||
}
|
||||
ast::ItemMod(ref m) => {
|
||||
let qualname = format!("::{}", self.analysis.ty_cx.map.path_to_string(item.id));
|
||||
|
||||
let cm = self.sess.codemap();
|
||||
let filename = cm.span_to_filename(m.inner);
|
||||
|
||||
let sub_span = self.span_utils.sub_span_after_keyword(item.span, keywords::Mod);
|
||||
|
||||
Data::ModData(ModData {
|
||||
id: item.id,
|
||||
name: get_ident(item.ident).to_string(),
|
||||
qualname: qualname,
|
||||
span: sub_span.unwrap(),
|
||||
scope: self.analysis.ty_cx.map.get_parent(item.id),
|
||||
filename: filename,
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
// FIXME
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_expr_data(&self, expr: &ast::Expr) -> Data {
|
||||
match expr.node {
|
||||
ast::ExprField(ref sub_ex, ident) => {
|
||||
let ty = &ty::expr_ty_adjusted(&self.analysis.ty_cx, &sub_ex).sty;
|
||||
match *ty {
|
||||
ty::ty_struct(def_id, _) => {
|
||||
let fields = ty::lookup_struct_fields(&self.analysis.ty_cx, def_id);
|
||||
for f in &fields {
|
||||
if f.name == ident.node.name {
|
||||
let sub_span = self.span_utils.span_for_last_ident(expr.span);
|
||||
return Data::VariableRefData(VariableRefData {
|
||||
name: get_ident(ident.node).to_string(),
|
||||
span: sub_span.unwrap(),
|
||||
scope: self.analysis.ty_cx.map.get_parent(expr.id),
|
||||
ref_id: f.id,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
self.sess.span_bug(expr.span,
|
||||
&format!("Couldn't find field {} on {:?}",
|
||||
&get_ident(ident.node),
|
||||
ty))
|
||||
}
|
||||
_ => self.sess.span_bug(expr.span,
|
||||
&format!("Expected struct type, found {:?}", ty)),
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// FIXME
|
||||
unimplemented!();
|
||||
|
|
Loading…
Reference in New Issue