Auto merge of #36487 - nrc:save-doc-urls, r=@eddyb
save-analysis: better 'parent' info In particular, this fixes some bugs displaying doc URLs for method calls.
This commit is contained in:
commit
55bf6a4f87
@ -167,7 +167,7 @@ pub struct FunctionData {
|
||||
pub scope: NodeId,
|
||||
pub value: String,
|
||||
pub visibility: Visibility,
|
||||
pub parent: Option<NodeId>,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
}
|
||||
|
||||
@ -250,6 +250,7 @@ pub struct MethodData {
|
||||
pub scope: NodeId,
|
||||
pub value: String,
|
||||
pub decl_id: Option<DefId>,
|
||||
pub parent: Option<DefId>,
|
||||
pub visibility: Visibility,
|
||||
pub docs: String,
|
||||
}
|
||||
@ -300,7 +301,7 @@ pub struct StructVariantData {
|
||||
pub type_value: String,
|
||||
pub value: String,
|
||||
pub scope: NodeId,
|
||||
pub parent: Option<NodeId>,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
}
|
||||
|
||||
@ -326,7 +327,7 @@ pub struct TupleVariantData {
|
||||
pub type_value: String,
|
||||
pub value: String,
|
||||
pub scope: NodeId,
|
||||
pub parent: Option<NodeId>,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
}
|
||||
|
||||
@ -339,7 +340,7 @@ pub struct TypeDefData {
|
||||
pub qualname: String,
|
||||
pub value: String,
|
||||
pub visibility: Visibility,
|
||||
pub parent: Option<NodeId>,
|
||||
pub parent: Option<DefId>,
|
||||
pub docs: String,
|
||||
}
|
||||
|
||||
@ -380,7 +381,7 @@ pub struct VariableData {
|
||||
pub qualname: String,
|
||||
pub span: Span,
|
||||
pub scope: NodeId,
|
||||
pub parent: Option<NodeId>,
|
||||
pub parent: Option<DefId>,
|
||||
pub value: String,
|
||||
pub type_value: String,
|
||||
pub visibility: Visibility,
|
||||
|
@ -27,9 +27,10 @@
|
||||
//! is used for recording the output in a format-agnostic way (see CsvDumper
|
||||
//! for an example).
|
||||
|
||||
use rustc::hir;
|
||||
use rustc::hir::def::Def;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::hir::map::Node;
|
||||
use rustc::hir::map::{Node, NodeItem};
|
||||
use rustc::session::Session;
|
||||
use rustc::ty::{self, TyCtxt, ImplOrTraitItem, ImplOrTraitItemContainer};
|
||||
|
||||
@ -47,7 +48,7 @@
|
||||
use super::{escape, generated_code, SaveContext, PathCollector, docs_for_attrs};
|
||||
use super::data::*;
|
||||
use super::dump::Dump;
|
||||
use super::external_data::Lower;
|
||||
use super::external_data::{Lower, make_def_id};
|
||||
use super::span_utils::SpanUtils;
|
||||
use super::recorder;
|
||||
|
||||
@ -271,11 +272,13 @@ fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) {
|
||||
|
||||
// looks up anything, not just a type
|
||||
fn lookup_type_ref(&self, ref_id: NodeId) -> Option<DefId> {
|
||||
match self.tcx.expect_def(ref_id) {
|
||||
Def::PrimTy(..) => None,
|
||||
Def::SelfTy(..) => None,
|
||||
def => Some(def.def_id()),
|
||||
}
|
||||
self.tcx.expect_def_or_none(ref_id).and_then(|def| {
|
||||
match def {
|
||||
Def::PrimTy(..) => None,
|
||||
Def::SelfTy(..) => None,
|
||||
def => Some(def.def_id()),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn process_def_kind(&mut self,
|
||||
@ -399,20 +402,36 @@ fn process_method(&mut self,
|
||||
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);
|
||||
let mut trait_id;
|
||||
let mut decl_id = None;
|
||||
match container {
|
||||
ImplOrTraitItemContainer::ImplContainer(id) => {
|
||||
trait_id = self.tcx.trait_id_of_impl(id);
|
||||
|
||||
match trait_id {
|
||||
Some(id) => {
|
||||
for item in &**self.tcx.trait_items(id) {
|
||||
if let &ImplOrTraitItem::MethodTraitItem(ref m) = item {
|
||||
if m.name == name {
|
||||
decl_id = Some(m.def_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if let Some(NodeItem(item)) = self.tcx.map.get_if_local(id) {
|
||||
if let hir::ItemImpl(_, _, _, _, ref ty, _) = item.node {
|
||||
trait_id = self.lookup_type_ref(ty.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
}
|
||||
ImplOrTraitItemContainer::TraitContainer(id) => {
|
||||
trait_id = Some(id);
|
||||
}
|
||||
}
|
||||
|
||||
self.dumper.method(MethodData {
|
||||
id: method_data.id,
|
||||
@ -422,6 +441,7 @@ fn process_method(&mut self,
|
||||
qualname: method_data.qualname.clone(),
|
||||
value: sig_str,
|
||||
decl_id: decl_id,
|
||||
parent: trait_id,
|
||||
visibility: vis,
|
||||
docs: docs_for_attrs(attrs),
|
||||
}.lower(self.tcx));
|
||||
@ -544,7 +564,7 @@ fn process_assoc_const(&mut self,
|
||||
span: Span,
|
||||
typ: &ast::Ty,
|
||||
expr: &ast::Expr,
|
||||
parent_id: NodeId,
|
||||
parent_id: DefId,
|
||||
vis: Visibility,
|
||||
attrs: &[Attribute]) {
|
||||
let qualname = format!("::{}", self.tcx.node_path_str(id));
|
||||
@ -659,7 +679,7 @@ fn process_enum(&mut self,
|
||||
type_value: enum_data.qualname.clone(),
|
||||
value: val,
|
||||
scope: enum_data.scope,
|
||||
parent: Some(item.id),
|
||||
parent: Some(make_def_id(item.id, &self.tcx.map)),
|
||||
docs: docs_for_attrs(&variant.node.attrs),
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
@ -684,7 +704,7 @@ fn process_enum(&mut self,
|
||||
type_value: enum_data.qualname.clone(),
|
||||
value: val,
|
||||
scope: enum_data.scope,
|
||||
parent: Some(item.id),
|
||||
parent: Some(make_def_id(item.id, &self.tcx.map)),
|
||||
docs: docs_for_attrs(&variant.node.attrs),
|
||||
}.lower(self.tcx));
|
||||
}
|
||||
@ -738,7 +758,8 @@ fn process_impl(&mut self,
|
||||
}
|
||||
self.process_generic_params(type_parameters, item.span, "", item.id);
|
||||
for impl_item in impl_items {
|
||||
self.process_impl_item(impl_item, item.id);
|
||||
let map = &self.tcx.map;
|
||||
self.process_impl_item(impl_item, make_def_id(item.id, map));
|
||||
}
|
||||
}
|
||||
|
||||
@ -809,7 +830,8 @@ fn process_trait(&mut self,
|
||||
// walk generics and methods
|
||||
self.process_generic_params(generics, item.span, &qualname, item.id);
|
||||
for method in methods {
|
||||
self.process_trait_item(method, item.id)
|
||||
let map = &self.tcx.map;
|
||||
self.process_trait_item(method, make_def_id(item.id, map))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1076,7 +1098,7 @@ fn process_macro_use(&mut self, span: Span, id: NodeId) {
|
||||
}
|
||||
}
|
||||
|
||||
fn process_trait_item(&mut self, trait_item: &ast::TraitItem, trait_id: NodeId) {
|
||||
fn process_trait_item(&mut self, trait_item: &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)) => {
|
||||
@ -1104,7 +1126,7 @@ fn process_trait_item(&mut self, trait_item: &ast::TraitItem, trait_id: NodeId)
|
||||
}
|
||||
}
|
||||
|
||||
fn process_impl_item(&mut self, impl_item: &ast::ImplItem, impl_id: NodeId) {
|
||||
fn process_impl_item(&mut self, impl_item: &ast::ImplItem, impl_id: DefId) {
|
||||
self.process_macro_use(impl_item.span, impl_item.id);
|
||||
match impl_item.node {
|
||||
ast::ImplItemKind::Const(ref ty, ref expr) => {
|
||||
|
@ -23,7 +23,7 @@ pub trait Lower {
|
||||
fn lower(self, tcx: TyCtxt) -> Self::Target;
|
||||
}
|
||||
|
||||
fn make_def_id(id: NodeId, map: &Map) -> DefId {
|
||||
pub fn make_def_id(id: NodeId, map: &Map) -> DefId {
|
||||
map.opt_local_def_id(id).unwrap_or(null_def_id())
|
||||
}
|
||||
|
||||
@ -188,7 +188,7 @@ fn lower(self, tcx: TyCtxt) -> FunctionData {
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
value: self.value,
|
||||
visibility: self.visibility,
|
||||
parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
|
||||
parent: self.parent,
|
||||
docs: self.docs,
|
||||
}
|
||||
}
|
||||
@ -353,7 +353,7 @@ fn lower(self, tcx: TyCtxt) -> MethodData {
|
||||
value: self.value,
|
||||
decl_id: self.decl_id,
|
||||
visibility: self.visibility,
|
||||
parent: Some(make_def_id(self.scope, &tcx.map)),
|
||||
parent: self.parent,
|
||||
docs: self.docs,
|
||||
}
|
||||
}
|
||||
@ -471,7 +471,7 @@ fn lower(self, tcx: TyCtxt) -> StructVariantData {
|
||||
type_value: self.type_value,
|
||||
value: self.value,
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
|
||||
parent: self.parent,
|
||||
docs: self.docs,
|
||||
}
|
||||
}
|
||||
@ -533,7 +533,7 @@ fn lower(self, tcx: TyCtxt) -> TupleVariantData {
|
||||
type_value: self.type_value,
|
||||
value: self.value,
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
|
||||
parent: self.parent,
|
||||
docs: self.docs,
|
||||
}
|
||||
}
|
||||
@ -563,7 +563,7 @@ fn lower(self, tcx: TyCtxt) -> TypeDefData {
|
||||
qualname: self.qualname,
|
||||
value: self.value,
|
||||
visibility: self.visibility,
|
||||
parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
|
||||
parent: self.parent,
|
||||
docs: self.docs,
|
||||
}
|
||||
}
|
||||
@ -668,7 +668,7 @@ fn lower(self, tcx: TyCtxt) -> VariableData {
|
||||
scope: make_def_id(self.scope, &tcx.map),
|
||||
value: self.value,
|
||||
type_value: self.type_value,
|
||||
parent: self.parent.map(|id| make_def_id(id, &tcx.map)),
|
||||
parent: self.parent,
|
||||
visibility: self.visibility,
|
||||
docs: self.docs,
|
||||
}
|
||||
|
@ -64,6 +64,7 @@
|
||||
pub use self::json_api_dumper::JsonApiDumper;
|
||||
pub use self::json_dumper::JsonDumper;
|
||||
pub use self::data::*;
|
||||
pub use self::external_data::make_def_id;
|
||||
pub use self::dump::Dump;
|
||||
pub use self::dump_visitor::DumpVisitor;
|
||||
use self::span_utils::SpanUtils;
|
||||
@ -295,7 +296,7 @@ pub fn get_field_data(&self, field: &ast::StructField,
|
||||
qualname: qualname,
|
||||
span: sub_span.unwrap(),
|
||||
scope: scope,
|
||||
parent: Some(scope),
|
||||
parent: Some(make_def_id(scope, &self.tcx.map)),
|
||||
value: "".to_owned(),
|
||||
type_value: typ,
|
||||
visibility: From::from(&field.vis),
|
||||
@ -312,7 +313,8 @@ pub fn get_method_data(&self, 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
|
||||
// which the method is declared in, followed by the method's name.
|
||||
let (qualname, vis, docs) = match self.tcx.impl_of_method(self.tcx.map.local_def_id(id)) {
|
||||
let (qualname, parent_scope, vis, docs) =
|
||||
match self.tcx.impl_of_method(self.tcx.map.local_def_id(id)) {
|
||||
Some(impl_id) => match self.tcx.map.get_if_local(impl_id) {
|
||||
Some(NodeItem(item)) => {
|
||||
match item.node {
|
||||
@ -320,12 +322,13 @@ pub fn get_method_data(&self, id: ast::NodeId,
|
||||
let mut result = String::from("<");
|
||||
result.push_str(&rustc::hir::print::ty_to_string(&ty));
|
||||
|
||||
if let Some(def_id) = self.tcx.trait_id_of_impl(impl_id) {
|
||||
let trait_id = self.tcx.trait_id_of_impl(impl_id);
|
||||
if let Some(def_id) = trait_id {
|
||||
result.push_str(" as ");
|
||||
result.push_str(&self.tcx.item_path_str(def_id));
|
||||
}
|
||||
result.push_str(">");
|
||||
(result, From::from(&item.vis), docs_for_attrs(&item.attrs))
|
||||
(result, trait_id, From::from(&item.vis), docs_for_attrs(&item.attrs))
|
||||
}
|
||||
_ => {
|
||||
span_bug!(span,
|
||||
@ -348,6 +351,7 @@ pub fn get_method_data(&self, id: ast::NodeId,
|
||||
match self.tcx.map.get_if_local(def_id) {
|
||||
Some(NodeItem(item)) => {
|
||||
(format!("::{}", self.tcx.item_path_str(def_id)),
|
||||
Some(def_id),
|
||||
From::from(&item.vis),
|
||||
docs_for_attrs(&item.attrs))
|
||||
}
|
||||
@ -381,7 +385,6 @@ pub fn get_method_data(&self, id: ast::NodeId,
|
||||
|
||||
let sub_span = self.span_utils.sub_span_after_keyword(span, keywords::Fn);
|
||||
filter!(self.span_utils, sub_span, span, None);
|
||||
let parent_scope = self.enclosing_scope(id);
|
||||
Some(FunctionData {
|
||||
id: id,
|
||||
name: name.to_string(),
|
||||
@ -392,7 +395,7 @@ pub fn get_method_data(&self, id: ast::NodeId,
|
||||
// FIXME you get better data here by using the visitor.
|
||||
value: String::new(),
|
||||
visibility: vis,
|
||||
parent: Some(parent_scope),
|
||||
parent: parent_scope,
|
||||
docs: docs,
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user