Skip to content

Commit cb7fcdd

Browse files
committed
Impl and trait item sigs
1 parent 5ebb0e2 commit cb7fcdd

File tree

3 files changed

+178
-27
lines changed

3 files changed

+178
-27
lines changed

src/librustc_save_analysis/dump_visitor.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -392,13 +392,13 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
392392
sig: &'l ast::MethodSig,
393393
body: Option<&'l ast::Block>,
394394
id: ast::NodeId,
395-
name: ast::Name,
395+
name: ast::Ident,
396396
vis: Visibility,
397397
attrs: &'l [Attribute],
398398
span: Span) {
399399
debug!("process_method: {}:{}", id, name);
400400

401-
if let Some(method_data) = self.save_ctxt.get_method_data(id, name, span) {
401+
if let Some(method_data) = self.save_ctxt.get_method_data(id, name.name, span) {
402402

403403
let sig_str = ::make_signature(&sig.decl, &sig.generics);
404404
if body.is_some() {
@@ -424,7 +424,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
424424
Some(id) => {
425425
for item in self.tcx.associated_items(id) {
426426
if item.kind == ty::AssociatedKind::Method {
427-
if item.name == name {
427+
if item.name == name.name {
428428
decl_id = Some(item.def_id);
429429
break;
430430
}
@@ -456,7 +456,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
456456
parent: trait_id,
457457
visibility: vis,
458458
docs: docs_for_attrs(attrs),
459-
sig: method_data.sig,
459+
sig: sig::method_signature(id, name, sig, &self.save_ctxt),
460460
attributes: attrs.to_vec(),
461461
}.lower(self.tcx));
462462
}
@@ -581,13 +581,14 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
581581
name: ast::Name,
582582
span: Span,
583583
typ: &'l ast::Ty,
584-
expr: &'l ast::Expr,
584+
expr: Option<&'l ast::Expr>,
585585
parent_id: DefId,
586586
vis: Visibility,
587587
attrs: &'l [Attribute]) {
588588
let qualname = format!("::{}", self.tcx.node_path_str(id));
589589

590590
let sub_span = self.span.sub_span_after_keyword(span, keywords::Const);
591+
let value = expr.map(|e| self.span.snippet(e.span)).unwrap_or(String::new());
591592

592593
if !self.span.filter_generated(sub_span, span) {
593594
self.dumper.variable(VariableData {
@@ -596,20 +597,22 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
596597
id: id,
597598
name: name.to_string(),
598599
qualname: qualname,
599-
value: self.span.snippet(expr.span),
600+
value: value,
600601
type_value: ty_to_string(&typ),
601602
scope: self.cur_scope,
602603
parent: Some(parent_id),
603604
visibility: vis,
604605
docs: docs_for_attrs(attrs),
605-
sig: None,
606+
sig: sig::assoc_const_signature(id, name, typ, expr, &self.save_ctxt),
606607
attributes: attrs.to_vec(),
607608
}.lower(self.tcx));
608609
}
609610

610611
// walk type and init value
611612
self.visit_ty(typ);
612-
self.visit_expr(expr);
613+
if let Some(expr) = expr {
614+
self.visit_expr(expr);
615+
}
613616
}
614617

615618
// FIXME tuple structs should generate tuple-specific data.
@@ -1122,12 +1125,12 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
11221125
fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId) {
11231126
self.process_macro_use(trait_item.span, trait_item.id);
11241127
match trait_item.node {
1125-
ast::TraitItemKind::Const(ref ty, Some(ref expr)) => {
1128+
ast::TraitItemKind::Const(ref ty, ref expr) => {
11261129
self.process_assoc_const(trait_item.id,
11271130
trait_item.ident.name,
11281131
trait_item.span,
11291132
&ty,
1130-
&expr,
1133+
expr.as_ref().map(|e| &**e),
11311134
trait_id,
11321135
Visibility::Public,
11331136
&trait_item.attrs);
@@ -1136,12 +1139,12 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
11361139
self.process_method(sig,
11371140
body.as_ref().map(|x| &**x),
11381141
trait_item.id,
1139-
trait_item.ident.name,
1142+
trait_item.ident,
11401143
Visibility::Public,
11411144
&trait_item.attrs,
11421145
trait_item.span);
11431146
}
1144-
ast::TraitItemKind::Type(ref _bounds, ref default_ty) => {
1147+
ast::TraitItemKind::Type(ref bounds, ref default_ty) => {
11451148
// FIXME do something with _bounds (for type refs)
11461149
let name = trait_item.ident.name.to_string();
11471150
let qualname = format!("::{}", self.tcx.node_path_str(trait_item.id));
@@ -1157,7 +1160,11 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
11571160
visibility: Visibility::Public,
11581161
parent: Some(trait_id),
11591162
docs: docs_for_attrs(&trait_item.attrs),
1160-
sig: None,
1163+
sig: sig::assoc_type_signature(trait_item.id,
1164+
trait_item.ident,
1165+
Some(bounds),
1166+
default_ty.as_ref().map(|ty| &**ty),
1167+
&self.save_ctxt),
11611168
attributes: trait_item.attrs.clone(),
11621169
}.lower(self.tcx));
11631170
}
@@ -1166,7 +1173,6 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
11661173
self.visit_ty(default_ty)
11671174
}
11681175
}
1169-
ast::TraitItemKind::Const(ref ty, None) => self.visit_ty(ty),
11701176
ast::TraitItemKind::Macro(_) => {}
11711177
}
11721178
}
@@ -1179,7 +1185,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
11791185
impl_item.ident.name,
11801186
impl_item.span,
11811187
&ty,
1182-
&expr,
1188+
Some(expr),
11831189
impl_id,
11841190
From::from(&impl_item.vis),
11851191
&impl_item.attrs);
@@ -1188,12 +1194,17 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
11881194
self.process_method(sig,
11891195
Some(body),
11901196
impl_item.id,
1191-
impl_item.ident.name,
1197+
impl_item.ident,
11921198
From::from(&impl_item.vis),
11931199
&impl_item.attrs,
11941200
impl_item.span);
11951201
}
1196-
ast::ImplItemKind::Type(ref ty) => self.visit_ty(ty),
1202+
ast::ImplItemKind::Type(ref ty) => {
1203+
// FIXME uses of the assoc type should ideally point to this
1204+
// 'def' and the name here should be a ref to the def in the
1205+
// trait.
1206+
self.visit_ty(ty)
1207+
}
11971208
ast::ImplItemKind::Macro(_) => {}
11981209
}
11991210
}

src/librustc_save_analysis/lib.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
369369

370370
// FIXME would be nice to take a MethodItem here, but the ast provides both
371371
// trait and impl flavours, so the caller must do the disassembly.
372-
pub fn get_method_data(&self, id: ast::NodeId,
373-
name: ast::Name, span: Span) -> Option<FunctionData> {
372+
pub fn get_method_data(&self,
373+
id: ast::NodeId,
374+
name: ast::Name,
375+
span: Span)
376+
-> Option<FunctionData> {
374377
// The qualname for a method is the trait name or name of the struct in an impl in
375378
// which the method is declared in, followed by the method's name.
376379
let (qualname, parent_scope, decl_id, vis, docs, attributes) =
@@ -460,7 +463,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
460463
visibility: vis,
461464
parent: parent_scope,
462465
docs: docs,
463-
// TODO
464466
sig: None,
465467
attributes: attributes,
466468
})

src/librustc_save_analysis/sig.rs

Lines changed: 145 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
//
1515
// ```
1616
// fn foo(x: String) {
17-
// println!("{}", x);
17+
// println!("{}", x);
1818
// }
1919
// ```
2020
// The signature string is something like "fn foo(x: String) {}" and the signature
@@ -63,6 +63,32 @@ pub fn variant_signature(variant: &ast::Variant, scx: &SaveContext) -> Option<Si
6363
variant.node.make(0, None, scx).ok()
6464
}
6565

66+
pub fn method_signature(id: NodeId,
67+
ident: ast::Ident,
68+
m: &ast::MethodSig,
69+
scx: &SaveContext)
70+
-> Option<Signature> {
71+
make_method_signature(id, ident, m, scx).ok()
72+
}
73+
74+
pub fn assoc_const_signature(id: NodeId,
75+
ident: ast::Name,
76+
ty: &ast::Ty,
77+
default: Option<&ast::Expr>,
78+
scx: &SaveContext)
79+
-> Option<Signature> {
80+
make_assoc_const_signature(id, ident, ty, default, scx).ok()
81+
}
82+
83+
pub fn assoc_type_signature(id: NodeId,
84+
ident: ast::Ident,
85+
bounds: Option<&ast::TyParamBounds>,
86+
default: Option<&ast::Ty>,
87+
scx: &SaveContext)
88+
-> Option<Signature> {
89+
make_assoc_type_signature(id, ident, bounds, default, scx).ok()
90+
}
91+
6692
type Result = ::std::result::Result<Signature, &'static str>;
6793

6894
trait Sig {
@@ -215,7 +241,7 @@ impl Sig for ast::Ty {
215241
format!("<{} as {}>::", nested_ty.text, first)
216242
} else {
217243
// FIXME handle path instead of elipses.
218-
format!("<{} as ...>::", nested_ty.text)
244+
format!("<{} as ...>::", nested_ty.text)
219245
};
220246

221247
let name = pprust::path_segment_to_string(path.segments.last().ok_or("Bad path")?);
@@ -263,7 +289,7 @@ impl Sig for ast::Ty {
263289
ast::TyKind::ImplicitSelf |
264290
ast::TyKind::Mac(_) => Err("Ty"),
265291
}
266-
}
292+
}
267293
}
268294

269295
impl Sig for ast::Item {
@@ -497,7 +523,7 @@ impl Sig for ast::Item {
497523

498524
let ty_sig = ty.make(offset + text.len(), id, scx)?;
499525
text.push_str(&ty_sig.text);
500-
526+
501527
text.push_str(" {}");
502528

503529
Ok(merge_sigs(text, vec![generics_sig, trait_sig, ty_sig]))
@@ -582,7 +608,9 @@ impl Sig for ast::Generics {
582608

583609
if !l.bounds.is_empty() {
584610
l_text.push_str(": ");
585-
let bounds = l.bounds.iter().map(|l| l.ident.to_string()).collect::<Vec<_>>().join(" + ");
611+
let bounds = l.bounds.iter().map(|l| {
612+
l.ident.to_string()
613+
}).collect::<Vec<_>>().join(" + ");
586614
l_text.push_str(&bounds);
587615
// FIXME add lifetime bounds refs.
588616
}
@@ -783,5 +811,115 @@ fn name_and_generics(mut text: String,
783811
}
784812

785813

786-
// TODO impl items, trait items
787-
// for impl/trait sigs - function for each kind, rather than use trait.
814+
fn make_assoc_type_signature(id: NodeId,
815+
ident: ast::Ident,
816+
bounds: Option<&ast::TyParamBounds>,
817+
default: Option<&ast::Ty>,
818+
scx: &SaveContext)
819+
-> Result {
820+
let mut text = "type ".to_owned();
821+
let name = ident.to_string();
822+
let mut defs = vec![SigElement {
823+
id: id_from_node_id(id, scx),
824+
start: text.len(),
825+
end: text.len() + name.len(),
826+
}];
827+
let mut refs = vec![];
828+
text.push_str(&name);
829+
if let Some(bounds) = bounds {
830+
text.push_str(": ");
831+
// FIXME should descend into bounds
832+
text.push_str(&pprust::bounds_to_string(bounds));
833+
}
834+
if let Some(default) = default {
835+
text.push_str(" = ");
836+
let ty_sig = default.make(text.len(), Some(id), scx)?;
837+
text.push_str(&ty_sig.text);
838+
defs.extend(ty_sig.defs.into_iter());
839+
refs.extend(ty_sig.refs.into_iter());
840+
}
841+
text.push(';');
842+
Ok(Signature { text, defs, refs })
843+
}
844+
845+
fn make_assoc_const_signature(id: NodeId,
846+
ident: ast::Name,
847+
ty: &ast::Ty,
848+
default: Option<&ast::Expr>,
849+
scx: &SaveContext)
850+
-> Result {
851+
let mut text = "const ".to_owned();
852+
let name = ident.to_string();
853+
let mut defs = vec![SigElement {
854+
id: id_from_node_id(id, scx),
855+
start: text.len(),
856+
end: text.len() + name.len(),
857+
}];
858+
let mut refs = vec![];
859+
text.push_str(&name);
860+
text.push_str(": ");
861+
862+
let ty_sig = ty.make(text.len(), Some(id), scx)?;
863+
text.push_str(&ty_sig.text);
864+
defs.extend(ty_sig.defs.into_iter());
865+
refs.extend(ty_sig.refs.into_iter());
866+
867+
if let Some(default) = default {
868+
text.push_str(" = ");
869+
text.push_str(&pprust::expr_to_string(default));
870+
}
871+
text.push(';');
872+
Ok(Signature { text, defs, refs })
873+
}
874+
875+
fn make_method_signature(id: NodeId,
876+
ident: ast::Ident,
877+
m: &ast::MethodSig,
878+
scx: &SaveContext)
879+
-> Result {
880+
// FIXME code dup with function signature
881+
let mut text = String::new();
882+
if m.constness.node == ast::Constness::Const {
883+
text.push_str("const ");
884+
}
885+
if m.unsafety == ast::Unsafety::Unsafe {
886+
text.push_str("unsafe ");
887+
}
888+
if m.abi != ::syntax::abi::Abi::Rust {
889+
text.push_str("extern");
890+
text.push_str(&m.abi.to_string());
891+
text.push(' ');
892+
}
893+
text.push_str("fn ");
894+
895+
let mut sig = name_and_generics(text,
896+
0,
897+
&m.generics,
898+
id,
899+
ident,
900+
scx)?;
901+
902+
sig.text.push('(');
903+
for i in &m.decl.inputs {
904+
// FIXME shoudl descend into patterns to add defs.
905+
sig.text.push_str(&pprust::pat_to_string(&i.pat));
906+
sig.text.push_str(": ");
907+
let nested = i.ty.make(sig.text.len(), Some(i.id), scx)?;
908+
sig.text.push_str(&nested.text);
909+
sig.text.push(',');
910+
sig.defs.extend(nested.defs.into_iter());
911+
sig.refs.extend(nested.refs.into_iter());
912+
}
913+
sig.text.push(')');
914+
915+
if let ast::FunctionRetTy::Ty(ref t) = m.decl.output {
916+
sig.text.push_str(" -> ");
917+
let nested = t.make(sig.text.len(), None, scx)?;
918+
sig.text.push_str(&nested.text);
919+
sig.defs.extend(nested.defs.into_iter());
920+
sig.refs.extend(nested.refs.into_iter());
921+
}
922+
sig.text.push_str(" {}");
923+
924+
Ok(sig)
925+
}

0 commit comments

Comments
 (0)