diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 61fc9a9adfb09efb750fd630fca0e8fdb0e9c341..ea346d99e31b5a4ed47be3725d9a1cfb71001204 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -392,13 +392,13 @@ fn process_method(&mut self, sig: &'l ast::MethodSig, body: Option<&'l ast::Block>, id: ast::NodeId, - name: ast::Name, + name: ast::Ident, vis: Visibility, attrs: &'l [Attribute], span: Span) { debug!("process_method: {}:{}", id, name); - if let Some(method_data) = self.save_ctxt.get_method_data(id, name, span) { + if let Some(method_data) = self.save_ctxt.get_method_data(id, name.name, span) { let sig_str = ::make_signature(&sig.decl, &sig.generics); if body.is_some() { @@ -424,7 +424,7 @@ fn process_method(&mut self, Some(id) => { for item in self.tcx.associated_items(id) { if item.kind == ty::AssociatedKind::Method { - if item.name == name { + if item.name == name.name { decl_id = Some(item.def_id); break; } @@ -456,7 +456,7 @@ fn process_method(&mut self, parent: trait_id, visibility: vis, docs: docs_for_attrs(attrs), - sig: method_data.sig, + sig: sig::method_signature(id, name, sig, &self.save_ctxt), attributes: attrs.to_vec(), }.lower(self.tcx)); } @@ -581,13 +581,14 @@ fn process_assoc_const(&mut self, name: ast::Name, span: Span, typ: &'l ast::Ty, - expr: &'l ast::Expr, + expr: Option<&'l ast::Expr>, parent_id: DefId, vis: Visibility, attrs: &'l [Attribute]) { let qualname = format!("::{}", self.tcx.node_path_str(id)); let sub_span = self.span.sub_span_after_keyword(span, keywords::Const); + let value = expr.map(|e| self.span.snippet(e.span)).unwrap_or(String::new()); if !self.span.filter_generated(sub_span, span) { self.dumper.variable(VariableData { @@ -596,20 +597,22 @@ fn process_assoc_const(&mut self, id: id, name: name.to_string(), qualname: qualname, - value: self.span.snippet(expr.span), + value: value, type_value: ty_to_string(&typ), scope: self.cur_scope, parent: Some(parent_id), visibility: vis, docs: docs_for_attrs(attrs), - sig: None, + sig: sig::assoc_const_signature(id, name, typ, expr, &self.save_ctxt), attributes: attrs.to_vec(), }.lower(self.tcx)); } // walk type and init value self.visit_ty(typ); - self.visit_expr(expr); + if let Some(expr) = expr { + self.visit_expr(expr); + } } // FIXME tuple structs should generate tuple-specific data. @@ -1122,12 +1125,12 @@ fn process_macro_use(&mut self, span: Span, id: NodeId) { fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId) { self.process_macro_use(trait_item.span, trait_item.id); match trait_item.node { - ast::TraitItemKind::Const(ref ty, Some(ref expr)) => { + ast::TraitItemKind::Const(ref ty, ref expr) => { self.process_assoc_const(trait_item.id, trait_item.ident.name, trait_item.span, &ty, - &expr, + expr.as_ref().map(|e| &**e), trait_id, Visibility::Public, &trait_item.attrs); @@ -1136,12 +1139,12 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId self.process_method(sig, body.as_ref().map(|x| &**x), trait_item.id, - trait_item.ident.name, + trait_item.ident, Visibility::Public, &trait_item.attrs, trait_item.span); } - ast::TraitItemKind::Type(ref _bounds, ref default_ty) => { + ast::TraitItemKind::Type(ref bounds, ref default_ty) => { // FIXME do something with _bounds (for type refs) let name = trait_item.ident.name.to_string(); let qualname = format!("::{}", self.tcx.node_path_str(trait_item.id)); @@ -1157,7 +1160,11 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId visibility: Visibility::Public, parent: Some(trait_id), docs: docs_for_attrs(&trait_item.attrs), - sig: None, + sig: sig::assoc_type_signature(trait_item.id, + trait_item.ident, + Some(bounds), + default_ty.as_ref().map(|ty| &**ty), + &self.save_ctxt), attributes: trait_item.attrs.clone(), }.lower(self.tcx)); } @@ -1166,7 +1173,6 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId self.visit_ty(default_ty) } } - ast::TraitItemKind::Const(ref ty, None) => self.visit_ty(ty), ast::TraitItemKind::Macro(_) => {} } } @@ -1179,7 +1185,7 @@ fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) { impl_item.ident.name, impl_item.span, &ty, - &expr, + Some(expr), impl_id, From::from(&impl_item.vis), &impl_item.attrs); @@ -1188,12 +1194,17 @@ fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) { self.process_method(sig, Some(body), impl_item.id, - impl_item.ident.name, + impl_item.ident, From::from(&impl_item.vis), &impl_item.attrs, impl_item.span); } - ast::ImplItemKind::Type(ref ty) => self.visit_ty(ty), + ast::ImplItemKind::Type(ref ty) => { + // FIXME uses of the assoc type should ideally point to this + // 'def' and the name here should be a ref to the def in the + // trait. + self.visit_ty(ty) + } ast::ImplItemKind::Macro(_) => {} } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 8e280377ce2d6fa2d1d95ee7e1cf66f14fde5e34..4802494f08ead317b242dff8b8cceb95872dd3fd 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -369,8 +369,11 @@ pub fn get_field_data(&self, // FIXME would be nice to take a MethodItem here, but the ast provides both // trait and impl flavours, so the caller must do the disassembly. - pub fn get_method_data(&self, id: ast::NodeId, - name: ast::Name, span: Span) -> Option { + pub fn get_method_data(&self, + id: ast::NodeId, + name: ast::Name, + span: Span) + -> Option { // The qualname for a method is the trait name or name of the struct in an impl in // which the method is declared in, followed by the method's name. let (qualname, parent_scope, decl_id, vis, docs, attributes) = @@ -460,7 +463,6 @@ pub fn get_method_data(&self, id: ast::NodeId, visibility: vis, parent: parent_scope, docs: docs, - // TODO sig: None, attributes: attributes, }) diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index b2a62038dfc15c7a2357e04161d3d0cf51267e97..1d03ab1383af1853505fa5edc88043e94b5702fb 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -14,7 +14,7 @@ // // ``` // fn foo(x: String) { -// println!("{}", x); +// println!("{}", x); // } // ``` // 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 Option { + make_method_signature(id, ident, m, scx).ok() +} + +pub fn assoc_const_signature(id: NodeId, + ident: ast::Name, + ty: &ast::Ty, + default: Option<&ast::Expr>, + scx: &SaveContext) + -> Option { + make_assoc_const_signature(id, ident, ty, default, scx).ok() +} + +pub fn assoc_type_signature(id: NodeId, + ident: ast::Ident, + bounds: Option<&ast::TyParamBounds>, + default: Option<&ast::Ty>, + scx: &SaveContext) + -> Option { + make_assoc_type_signature(id, ident, bounds, default, scx).ok() +} + type Result = ::std::result::Result; trait Sig { @@ -215,7 +241,7 @@ fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext) -> format!("<{} as {}>::", nested_ty.text, first) } else { // FIXME handle path instead of elipses. - format!("<{} as ...>::", nested_ty.text) + format!("<{} as ...>::", nested_ty.text) }; let name = pprust::path_segment_to_string(path.segments.last().ok_or("Bad path")?); @@ -263,7 +289,7 @@ fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext) -> ast::TyKind::ImplicitSelf | ast::TyKind::Mac(_) => Err("Ty"), } - } + } } impl Sig for ast::Item { @@ -497,7 +523,7 @@ fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext) -> let ty_sig = ty.make(offset + text.len(), id, scx)?; text.push_str(&ty_sig.text); - + text.push_str(" {}"); Ok(merge_sigs(text, vec![generics_sig, trait_sig, ty_sig])) @@ -582,7 +608,9 @@ fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext) -> if !l.bounds.is_empty() { l_text.push_str(": "); - let bounds = l.bounds.iter().map(|l| l.ident.to_string()).collect::>().join(" + "); + let bounds = l.bounds.iter().map(|l| { + l.ident.to_string() + }).collect::>().join(" + "); l_text.push_str(&bounds); // FIXME add lifetime bounds refs. } @@ -783,5 +811,115 @@ fn name_and_generics(mut text: String, } -// TODO impl items, trait items -// for impl/trait sigs - function for each kind, rather than use trait. +fn make_assoc_type_signature(id: NodeId, + ident: ast::Ident, + bounds: Option<&ast::TyParamBounds>, + default: Option<&ast::Ty>, + scx: &SaveContext) + -> Result { + let mut text = "type ".to_owned(); + let name = ident.to_string(); + let mut defs = vec![SigElement { + id: id_from_node_id(id, scx), + start: text.len(), + end: text.len() + name.len(), + }]; + let mut refs = vec![]; + text.push_str(&name); + if let Some(bounds) = bounds { + text.push_str(": "); + // FIXME should descend into bounds + text.push_str(&pprust::bounds_to_string(bounds)); + } + if let Some(default) = default { + text.push_str(" = "); + let ty_sig = default.make(text.len(), Some(id), scx)?; + text.push_str(&ty_sig.text); + defs.extend(ty_sig.defs.into_iter()); + refs.extend(ty_sig.refs.into_iter()); + } + text.push(';'); + Ok(Signature { text, defs, refs }) +} + +fn make_assoc_const_signature(id: NodeId, + ident: ast::Name, + ty: &ast::Ty, + default: Option<&ast::Expr>, + scx: &SaveContext) + -> Result { + let mut text = "const ".to_owned(); + let name = ident.to_string(); + let mut defs = vec![SigElement { + id: id_from_node_id(id, scx), + start: text.len(), + end: text.len() + name.len(), + }]; + let mut refs = vec![]; + text.push_str(&name); + text.push_str(": "); + + let ty_sig = ty.make(text.len(), Some(id), scx)?; + text.push_str(&ty_sig.text); + defs.extend(ty_sig.defs.into_iter()); + refs.extend(ty_sig.refs.into_iter()); + + if let Some(default) = default { + text.push_str(" = "); + text.push_str(&pprust::expr_to_string(default)); + } + text.push(';'); + Ok(Signature { text, defs, refs }) +} + +fn make_method_signature(id: NodeId, + ident: ast::Ident, + m: &ast::MethodSig, + scx: &SaveContext) + -> Result { + // FIXME code dup with function signature + let mut text = String::new(); + if m.constness.node == ast::Constness::Const { + text.push_str("const "); + } + if m.unsafety == ast::Unsafety::Unsafe { + text.push_str("unsafe "); + } + if m.abi != ::syntax::abi::Abi::Rust { + text.push_str("extern"); + text.push_str(&m.abi.to_string()); + text.push(' '); + } + text.push_str("fn "); + + let mut sig = name_and_generics(text, + 0, + &m.generics, + id, + ident, + scx)?; + + sig.text.push('('); + for i in &m.decl.inputs { + // FIXME shoudl descend into patterns to add defs. + sig.text.push_str(&pprust::pat_to_string(&i.pat)); + sig.text.push_str(": "); + let nested = i.ty.make(sig.text.len(), Some(i.id), scx)?; + sig.text.push_str(&nested.text); + sig.text.push(','); + sig.defs.extend(nested.defs.into_iter()); + sig.refs.extend(nested.refs.into_iter()); + } + sig.text.push(')'); + + if let ast::FunctionRetTy::Ty(ref t) = m.decl.output { + sig.text.push_str(" -> "); + let nested = t.make(sig.text.len(), None, scx)?; + sig.text.push_str(&nested.text); + sig.defs.extend(nested.defs.into_iter()); + sig.refs.extend(nested.refs.into_iter()); + } + sig.text.push_str(" {}"); + + Ok(sig) +}