提交 cb7fcdd5 编写于 作者: N Nick Cameron

Impl and trait item sigs

上级 5ebb0e24
...@@ -392,13 +392,13 @@ fn process_method(&mut self, ...@@ -392,13 +392,13 @@ fn process_method(&mut self,
sig: &'l ast::MethodSig, sig: &'l ast::MethodSig,
body: Option<&'l ast::Block>, body: Option<&'l ast::Block>,
id: ast::NodeId, id: ast::NodeId,
name: ast::Name, name: ast::Ident,
vis: Visibility, vis: Visibility,
attrs: &'l [Attribute], attrs: &'l [Attribute],
span: Span) { span: Span) {
debug!("process_method: {}:{}", id, name); 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); let sig_str = ::make_signature(&sig.decl, &sig.generics);
if body.is_some() { if body.is_some() {
...@@ -424,7 +424,7 @@ fn process_method(&mut self, ...@@ -424,7 +424,7 @@ fn process_method(&mut self,
Some(id) => { Some(id) => {
for item in self.tcx.associated_items(id) { for item in self.tcx.associated_items(id) {
if item.kind == ty::AssociatedKind::Method { if item.kind == ty::AssociatedKind::Method {
if item.name == name { if item.name == name.name {
decl_id = Some(item.def_id); decl_id = Some(item.def_id);
break; break;
} }
...@@ -456,7 +456,7 @@ fn process_method(&mut self, ...@@ -456,7 +456,7 @@ fn process_method(&mut self,
parent: trait_id, parent: trait_id,
visibility: vis, visibility: vis,
docs: docs_for_attrs(attrs), docs: docs_for_attrs(attrs),
sig: method_data.sig, sig: sig::method_signature(id, name, sig, &self.save_ctxt),
attributes: attrs.to_vec(), attributes: attrs.to_vec(),
}.lower(self.tcx)); }.lower(self.tcx));
} }
...@@ -581,13 +581,14 @@ fn process_assoc_const(&mut self, ...@@ -581,13 +581,14 @@ fn process_assoc_const(&mut self,
name: ast::Name, name: ast::Name,
span: Span, span: Span,
typ: &'l ast::Ty, typ: &'l ast::Ty,
expr: &'l ast::Expr, expr: Option<&'l ast::Expr>,
parent_id: DefId, parent_id: DefId,
vis: Visibility, vis: Visibility,
attrs: &'l [Attribute]) { attrs: &'l [Attribute]) {
let qualname = format!("::{}", self.tcx.node_path_str(id)); let qualname = format!("::{}", self.tcx.node_path_str(id));
let sub_span = self.span.sub_span_after_keyword(span, keywords::Const); 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) { if !self.span.filter_generated(sub_span, span) {
self.dumper.variable(VariableData { self.dumper.variable(VariableData {
...@@ -596,21 +597,23 @@ fn process_assoc_const(&mut self, ...@@ -596,21 +597,23 @@ fn process_assoc_const(&mut self,
id: id, id: id,
name: name.to_string(), name: name.to_string(),
qualname: qualname, qualname: qualname,
value: self.span.snippet(expr.span), value: value,
type_value: ty_to_string(&typ), type_value: ty_to_string(&typ),
scope: self.cur_scope, scope: self.cur_scope,
parent: Some(parent_id), parent: Some(parent_id),
visibility: vis, visibility: vis,
docs: docs_for_attrs(attrs), docs: docs_for_attrs(attrs),
sig: None, sig: sig::assoc_const_signature(id, name, typ, expr, &self.save_ctxt),
attributes: attrs.to_vec(), attributes: attrs.to_vec(),
}.lower(self.tcx)); }.lower(self.tcx));
} }
// walk type and init value // walk type and init value
self.visit_ty(typ); self.visit_ty(typ);
if let Some(expr) = expr {
self.visit_expr(expr); self.visit_expr(expr);
} }
}
// FIXME tuple structs should generate tuple-specific data. // FIXME tuple structs should generate tuple-specific data.
fn process_struct(&mut self, fn process_struct(&mut self,
...@@ -1122,12 +1125,12 @@ fn process_macro_use(&mut self, span: Span, id: NodeId) { ...@@ -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) { fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId) {
self.process_macro_use(trait_item.span, trait_item.id); self.process_macro_use(trait_item.span, trait_item.id);
match trait_item.node { 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, self.process_assoc_const(trait_item.id,
trait_item.ident.name, trait_item.ident.name,
trait_item.span, trait_item.span,
&ty, &ty,
&expr, expr.as_ref().map(|e| &**e),
trait_id, trait_id,
Visibility::Public, Visibility::Public,
&trait_item.attrs); &trait_item.attrs);
...@@ -1136,12 +1139,12 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId ...@@ -1136,12 +1139,12 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId
self.process_method(sig, self.process_method(sig,
body.as_ref().map(|x| &**x), body.as_ref().map(|x| &**x),
trait_item.id, trait_item.id,
trait_item.ident.name, trait_item.ident,
Visibility::Public, Visibility::Public,
&trait_item.attrs, &trait_item.attrs,
trait_item.span); 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) // FIXME do something with _bounds (for type refs)
let name = trait_item.ident.name.to_string(); let name = trait_item.ident.name.to_string();
let qualname = format!("::{}", self.tcx.node_path_str(trait_item.id)); 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 ...@@ -1157,7 +1160,11 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId
visibility: Visibility::Public, visibility: Visibility::Public,
parent: Some(trait_id), parent: Some(trait_id),
docs: docs_for_attrs(&trait_item.attrs), 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(), attributes: trait_item.attrs.clone(),
}.lower(self.tcx)); }.lower(self.tcx));
} }
...@@ -1166,7 +1173,6 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId ...@@ -1166,7 +1173,6 @@ fn process_trait_item(&mut self, trait_item: &'l ast::TraitItem, trait_id: DefId
self.visit_ty(default_ty) self.visit_ty(default_ty)
} }
} }
ast::TraitItemKind::Const(ref ty, None) => self.visit_ty(ty),
ast::TraitItemKind::Macro(_) => {} ast::TraitItemKind::Macro(_) => {}
} }
} }
...@@ -1179,7 +1185,7 @@ fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) { ...@@ -1179,7 +1185,7 @@ fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) {
impl_item.ident.name, impl_item.ident.name,
impl_item.span, impl_item.span,
&ty, &ty,
&expr, Some(expr),
impl_id, impl_id,
From::from(&impl_item.vis), From::from(&impl_item.vis),
&impl_item.attrs); &impl_item.attrs);
...@@ -1188,12 +1194,17 @@ fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) { ...@@ -1188,12 +1194,17 @@ fn process_impl_item(&mut self, impl_item: &'l ast::ImplItem, impl_id: DefId) {
self.process_method(sig, self.process_method(sig,
Some(body), Some(body),
impl_item.id, impl_item.id,
impl_item.ident.name, impl_item.ident,
From::from(&impl_item.vis), From::from(&impl_item.vis),
&impl_item.attrs, &impl_item.attrs,
impl_item.span); 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(_) => {} ast::ImplItemKind::Macro(_) => {}
} }
} }
......
...@@ -369,8 +369,11 @@ pub fn get_field_data(&self, ...@@ -369,8 +369,11 @@ pub fn get_field_data(&self,
// FIXME would be nice to take a MethodItem here, but the ast provides both // 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. // trait and impl flavours, so the caller must do the disassembly.
pub fn get_method_data(&self, id: ast::NodeId, pub fn get_method_data(&self,
name: ast::Name, span: Span) -> Option<FunctionData> { id: ast::NodeId,
name: ast::Name,
span: Span)
-> Option<FunctionData> {
// The qualname for a method is the trait name or name of the struct in an impl in // 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. // which the method is declared in, followed by the method's name.
let (qualname, parent_scope, decl_id, vis, docs, attributes) = let (qualname, parent_scope, decl_id, vis, docs, attributes) =
...@@ -460,7 +463,6 @@ pub fn get_method_data(&self, id: ast::NodeId, ...@@ -460,7 +463,6 @@ pub fn get_method_data(&self, id: ast::NodeId,
visibility: vis, visibility: vis,
parent: parent_scope, parent: parent_scope,
docs: docs, docs: docs,
// TODO
sig: None, sig: None,
attributes: attributes, attributes: attributes,
}) })
......
...@@ -63,6 +63,32 @@ pub fn variant_signature(variant: &ast::Variant, scx: &SaveContext) -> Option<Si ...@@ -63,6 +63,32 @@ pub fn variant_signature(variant: &ast::Variant, scx: &SaveContext) -> Option<Si
variant.node.make(0, None, scx).ok() variant.node.make(0, None, scx).ok()
} }
pub fn method_signature(id: NodeId,
ident: ast::Ident,
m: &ast::MethodSig,
scx: &SaveContext)
-> Option<Signature> {
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<Signature> {
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<Signature> {
make_assoc_type_signature(id, ident, bounds, default, scx).ok()
}
type Result = ::std::result::Result<Signature, &'static str>; type Result = ::std::result::Result<Signature, &'static str>;
trait Sig { trait Sig {
...@@ -582,7 +608,9 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) -> ...@@ -582,7 +608,9 @@ fn make(&self, offset: usize, _parent_id: Option<NodeId>, scx: &SaveContext) ->
if !l.bounds.is_empty() { if !l.bounds.is_empty() {
l_text.push_str(": "); l_text.push_str(": ");
let bounds = l.bounds.iter().map(|l| l.ident.to_string()).collect::<Vec<_>>().join(" + "); let bounds = l.bounds.iter().map(|l| {
l.ident.to_string()
}).collect::<Vec<_>>().join(" + ");
l_text.push_str(&bounds); l_text.push_str(&bounds);
// FIXME add lifetime bounds refs. // FIXME add lifetime bounds refs.
} }
...@@ -783,5 +811,115 @@ fn name_and_generics(mut text: String, ...@@ -783,5 +811,115 @@ fn name_and_generics(mut text: String,
} }
// TODO impl items, trait items fn make_assoc_type_signature(id: NodeId,
// for impl/trait sigs - function for each kind, rather than use trait. 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)
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册