Impl and trait item sigs
This commit is contained in:
parent
5ebb0e2498
commit
cb7fcdd520
|
@ -392,13 +392,13 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
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 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
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 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
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 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
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,20 +597,22 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
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);
|
||||||
self.visit_expr(expr);
|
if let Some(expr) = expr {
|
||||||
|
self.visit_expr(expr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME tuple structs should generate tuple-specific data.
|
// 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> {
|
||||||
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 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
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 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
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 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
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 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
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 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
|
||||||
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 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||||
|
|
||||||
// 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 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
|
||||||
visibility: vis,
|
visibility: vis,
|
||||||
parent: parent_scope,
|
parent: parent_scope,
|
||||||
docs: docs,
|
docs: docs,
|
||||||
// TODO
|
|
||||||
sig: None,
|
sig: None,
|
||||||
attributes: attributes,
|
attributes: attributes,
|
||||||
})
|
})
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
//
|
//
|
||||||
// ```
|
// ```
|
||||||
// fn foo(x: String) {
|
// fn foo(x: String) {
|
||||||
// println!("{}", x);
|
// println!("{}", x);
|
||||||
// }
|
// }
|
||||||
// ```
|
// ```
|
||||||
// The signature string is something like "fn foo(x: String) {}" and the signature
|
// 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
|
||||||
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 {
|
||||||
|
@ -215,7 +241,7 @@ impl Sig for ast::Ty {
|
||||||
format!("<{} as {}>::", nested_ty.text, first)
|
format!("<{} as {}>::", nested_ty.text, first)
|
||||||
} else {
|
} else {
|
||||||
// FIXME handle path instead of elipses.
|
// 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")?);
|
let name = pprust::path_segment_to_string(path.segments.last().ok_or("Bad path")?);
|
||||||
|
@ -263,7 +289,7 @@ impl Sig for ast::Ty {
|
||||||
ast::TyKind::ImplicitSelf |
|
ast::TyKind::ImplicitSelf |
|
||||||
ast::TyKind::Mac(_) => Err("Ty"),
|
ast::TyKind::Mac(_) => Err("Ty"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sig for ast::Item {
|
impl Sig for ast::Item {
|
||||||
|
@ -497,7 +523,7 @@ impl Sig for ast::Item {
|
||||||
|
|
||||||
let ty_sig = ty.make(offset + text.len(), id, scx)?;
|
let ty_sig = ty.make(offset + text.len(), id, scx)?;
|
||||||
text.push_str(&ty_sig.text);
|
text.push_str(&ty_sig.text);
|
||||||
|
|
||||||
text.push_str(" {}");
|
text.push_str(" {}");
|
||||||
|
|
||||||
Ok(merge_sigs(text, vec![generics_sig, trait_sig, ty_sig]))
|
Ok(merge_sigs(text, vec![generics_sig, trait_sig, ty_sig]))
|
||||||
|
@ -582,7 +608,9 @@ impl Sig for ast::Generics {
|
||||||
|
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 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)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue