about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2016-06-16 11:28:39 +0100
committerNick Cameron <ncameron@mozilla.com>2016-06-16 11:28:39 +0100
commita835d7487cc729a2a64149709229fb62af2d78fc (patch)
treec05184188bf26b76851426b8665d4764f1672fac /src
parentc28374ef0b1b787ba039f55341caae88081ccc78 (diff)
downloadrust-a835d7487cc729a2a64149709229fb62af2d78fc.tar.gz
rust-a835d7487cc729a2a64149709229fb62af2d78fc.zip
save-analysis: add a decl_id for methods
This is non-null if the method is in a (non-inherent) impl and in that case will be the id for the method declaration in the implemented trait.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_save_analysis/data.rs1
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs52
-rw-r--r--src/librustc_save_analysis/external_data.rs2
-rw-r--r--src/librustc_save_analysis/json_dumper.rs12
4 files changed, 50 insertions, 17 deletions
diff --git a/src/librustc_save_analysis/data.rs b/src/librustc_save_analysis/data.rs
index 94e2a52c6ad..15aaa77cc35 100644
--- a/src/librustc_save_analysis/data.rs
+++ b/src/librustc_save_analysis/data.rs
@@ -214,6 +214,7 @@ pub struct MethodData {
     pub span: Span,
     pub scope: NodeId,
     pub value: String,
+    pub decl_id: Option<DefId>,
 }
 
 /// Data for modules.
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index a6bc6e180ac..56c7436a8fe 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -30,7 +30,7 @@
 use rustc::hir::def::Def;
 use rustc::hir::def_id::DefId;
 use rustc::session::Session;
-use rustc::ty::{self, TyCtxt};
+use rustc::ty::{self, TyCtxt, ImplOrTraitItem, ImplOrTraitItemContainer};
 
 use std::collections::HashSet;
 use std::hash::*;
@@ -381,24 +381,42 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
 
             let sig_str = ::make_signature(&sig.decl, &sig.generics);
             if body.is_some() {
-                if !self.span.filter_generated(Some(method_data.span), span) {
-                    let mut data = method_data.clone();
-                    data.value = sig_str;
-                    self.dumper.function(data.lower(self.tcx));
-                }
                 self.process_formals(&sig.decl.inputs, &method_data.qualname);
-            } else {
-                if !self.span.filter_generated(Some(method_data.span), span) {
-                    self.dumper.method(MethodData {
-                        id: method_data.id,
-                        name: method_data.name,
-                        span: method_data.span,
-                        scope: method_data.scope,
-                        qualname: method_data.qualname.clone(),
-                        value: sig_str,
-                    }.lower(self.tcx));
-                }
             }
+
+            // If the method is defined in an impl, then try and find the corresponding
+            // method decl in a trait, and if there is one, make a decl_id for it. This
+            // requires looking up the impl, then the trait, then searching for a method
+            // with the right name.
+            if !self.span.filter_generated(Some(method_data.span), span) {
+                let container =
+                    self.tcx.impl_or_trait_item(self.tcx.map.local_def_id(id)).container();
+                let decl_id = if let ImplOrTraitItemContainer::ImplContainer(id) = container {
+                    self.tcx.trait_id_of_impl(id).and_then(|id| {
+                        for item in &**self.tcx.trait_items(id) {
+                            if let &ImplOrTraitItem::MethodTraitItem(ref m) = item {
+                                if m.name == name {
+                                    return Some(m.def_id);
+                                }
+                            }
+                        }
+                        None
+                    })
+                } else {
+                    None
+                };
+
+                self.dumper.method(MethodData {
+                    id: method_data.id,
+                    name: method_data.name,
+                    span: method_data.span,
+                    scope: method_data.scope,
+                    qualname: method_data.qualname.clone(),
+                    value: sig_str,
+                    decl_id: decl_id,
+                }.lower(self.tcx));
+            }
+
             self.process_generic_params(&sig.generics, span, &method_data.qualname, id);
         }
 
diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs
index 3c59765e6c1..7efd2624561 100644
--- a/src/librustc_save_analysis/external_data.rs
+++ b/src/librustc_save_analysis/external_data.rs
@@ -321,6 +321,7 @@ pub struct MethodData {
     pub span: SpanData,
     pub scope: DefId,
     pub value: String,
+    pub decl_id: Option<DefId>,
 }
 
 impl Lower for data::MethodData {
@@ -334,6 +335,7 @@ impl Lower for data::MethodData {
             id: make_def_id(self.id, &tcx.map),
             qualname: self.qualname,
             value: self.value,
+            decl_id: self.decl_id,
         }
     }
 }
diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs
index f1ca127667c..b1955cbd7b8 100644
--- a/src/librustc_save_analysis/json_dumper.rs
+++ b/src/librustc_save_analysis/json_dumper.rs
@@ -182,6 +182,7 @@ struct Def {
     qualname: String,
     value: String,
     children: Vec<Id>,
+    decl_id: Option<Id>,
 }
 
 #[derive(Debug, RustcEncodable)]
@@ -221,6 +222,7 @@ impl From<EnumData> for Def {
             qualname: data.qualname,
             value: data.value,
             children: data.variants.into_iter().map(|id| From::from(id)).collect(),
+            decl_id: None,
         }
     }
 }
@@ -235,6 +237,7 @@ impl From<TupleVariantData> for Def {
             qualname: data.qualname,
             value: data.value,
             children: vec![],
+            decl_id: None,
         }
     }
 }
@@ -248,6 +251,7 @@ impl From<StructVariantData> for Def {
             qualname: data.qualname,
             value: data.value,
             children: vec![],
+            decl_id: None,
         }
     }
 }
@@ -261,6 +265,7 @@ impl From<StructData> for Def {
             qualname: data.qualname,
             value: data.value,
             children: data.fields.into_iter().map(|id| From::from(id)).collect(),
+            decl_id: None,
         }
     }
 }
@@ -274,6 +279,7 @@ impl From<TraitData> for Def {
             qualname: data.qualname,
             value: data.value,
             children: data.items.into_iter().map(|id| From::from(id)).collect(),
+            decl_id: None,
         }
     }
 }
@@ -287,6 +293,7 @@ impl From<FunctionData> for Def {
             qualname: data.qualname,
             value: data.value,
             children: vec![],
+            decl_id: None,
         }
     }
 }
@@ -300,6 +307,7 @@ impl From<MethodData> for Def {
             qualname: data.qualname,
             value: data.value,
             children: vec![],
+            decl_id: data.decl_id.map(|id| From::from(id)),
         }
     }
 }
@@ -313,6 +321,7 @@ impl From<MacroData> for Def {
             qualname: data.qualname,
             value: String::new(),
             children: vec![],
+            decl_id: None,
         }
     }
 }
@@ -326,6 +335,7 @@ impl From<ModData> for Def {
             qualname: data.qualname,
             value: data.filename,
             children: data.items.into_iter().map(|id| From::from(id)).collect(),
+            decl_id: None,
         }
     }
 }
@@ -339,6 +349,7 @@ impl From<TypeDefData> for Def {
             qualname: data.qualname,
             value: data.value,
             children: vec![],
+            decl_id: None,
         }
     }
 }
@@ -357,6 +368,7 @@ impl From<VariableData> for Def {
             qualname: data.qualname,
             value: data.value,
             children: vec![],
+            decl_id: None,
         }
     }
 }