提交 609d0bd8 编写于 作者: N Nick Cameron

dump data for prefix path segments

上级 c2bb7cad
......@@ -38,7 +38,6 @@
use syntax::print::pprust::{
bounds_to_string,
generic_params_to_string,
path_to_string,
ty_to_string
};
use syntax::ptr::P;
......@@ -218,95 +217,21 @@ pub fn dump_compilation_options(&mut self, input: &Input, crate_name: &str) {
self.dumper.compilation_opts(data);
}
// Return all non-empty prefixes of a path.
// For each prefix, we return the span for the last segment in the prefix and
// a str representation of the entire prefix.
fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> {
let segments = &path.segments[if path.is_global() { 1 } else { 0 }..];
let mut result = Vec::with_capacity(segments.len());
let mut segs = Vec::with_capacity(segments.len());
for (i, seg) in segments.iter().enumerate() {
segs.push(seg.clone());
let sub_path = ast::Path {
span: seg.ident.span, // span for the last segment
segments: segs,
};
let qualname = if i == 0 && path.is_global() {
format!("::{}", path_to_string(&sub_path))
} else {
path_to_string(&sub_path)
};
result.push((seg.ident.span, qualname));
segs = sub_path.segments;
}
result
}
fn write_sub_paths(&mut self, path: &ast::Path) {
let sub_paths = self.process_path_prefixes(path);
for (span, _) in sub_paths {
let span = self.span_from_span(span);
self.dumper.dump_ref(Ref {
kind: RefKind::Mod,
span,
ref_id: ::null_id(),
});
for seg in &path.segments {
if let Some(data) = self.save_ctxt.get_path_segment_data(seg) {
self.dumper.dump_ref(data);
}
}
}
// As write_sub_paths, but does not process the last ident in the path (assuming it
// will be processed elsewhere). See note on write_sub_paths about global.
fn write_sub_paths_truncated(&mut self, path: &ast::Path) {
let sub_paths = self.process_path_prefixes(path);
let len = sub_paths.len();
if len <= 1 {
return;
}
for (span, _) in sub_paths.into_iter().take(len - 1) {
let span = self.span_from_span(span);
self.dumper.dump_ref(Ref {
kind: RefKind::Mod,
span,
ref_id: ::null_id(),
});
}
}
// As write_sub_paths, but expects a path of the form module_path::trait::method
// Where trait could actually be a struct too.
fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) {
let sub_paths = self.process_path_prefixes(path);
let len = sub_paths.len();
if len <= 1 {
return;
}
let sub_paths = &sub_paths[..(len - 1)];
// write the trait part of the sub-path
let (ref span, _) = sub_paths[len - 2];
let span = self.span_from_span(*span);
self.dumper.dump_ref(Ref {
kind: RefKind::Type,
ref_id: ::null_id(),
span,
});
// write the other sub-paths
if len <= 2 {
return;
}
let sub_paths = &sub_paths[..len - 2];
for &(ref span, _) in sub_paths {
let span = self.span_from_span(*span);
self.dumper.dump_ref(Ref {
kind: RefKind::Mod,
span,
ref_id: ::null_id(),
});
for seg in &path.segments[..path.segments.len() - 1] {
if let Some(data) = self.save_ctxt.get_path_segment_data(seg) {
self.dumper.dump_ref(data);
}
}
}
......@@ -876,29 +801,7 @@ fn process_path(&mut self, id: NodeId, path: &'l ast::Path) {
}
}
// Modules or types in the path prefix.
match self.save_ctxt.get_path_def(id) {
HirDef::Method(did) => {
let ti = self.tcx.associated_item(did);
if ti.kind == ty::AssociatedKind::Method && ti.method_has_self_argument {
self.write_sub_path_trait_truncated(path);
}
}
HirDef::Fn(..) |
HirDef::Const(..) |
HirDef::Static(..) |
HirDef::StructCtor(..) |
HirDef::VariantCtor(..) |
HirDef::AssociatedConst(..) |
HirDef::Local(..) |
HirDef::Upvar(..) |
HirDef::Struct(..) |
HirDef::Union(..) |
HirDef::Variant(..) |
HirDef::TyAlias(..) |
HirDef::AssociatedTy(..) => self.write_sub_paths_truncated(path),
_ => {}
}
self.write_sub_paths_truncated(path);
}
fn process_struct_lit(
......
......@@ -684,13 +684,14 @@ pub fn get_path_def(&self, id: NodeId) -> HirDef {
}
}
pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option<Ref> {
pub fn get_path_data(&self, _id: NodeId, path: &ast::Path) -> Option<Ref> {
path.segments.last().and_then(|seg| self.get_path_segment_data(seg))
}
pub fn get_path_segment_data(&self, path_seg: &ast::PathSegment) -> Option<Ref> {
// Returns true if the path is function type sugar, e.g., `Fn(A) -> B`.
fn fn_type(path: &ast::Path) -> bool {
if path.segments.len() != 1 {
return false;
}
if let Some(ref generic_args) = path.segments[0].args {
fn fn_type(seg: &ast::PathSegment) -> bool {
if let Some(ref generic_args) = seg.args {
if let ast::GenericArgs::Parenthesized(_) = **generic_args {
return true;
}
......@@ -698,17 +699,13 @@ fn fn_type(path: &ast::Path) -> bool {
false
}
if path.segments.is_empty() {
return None;
}
let def = self.get_path_def(path_seg.id);
let span = path_seg.ident.span;
filter!(self.span_utils, span);
let span = self.span_from_span(span);
let def = self.get_path_def(id);
let last_seg = &path.segments[path.segments.len() - 1];
let sub_span = last_seg.ident.span;
filter!(self.span_utils, sub_span);
match def {
HirDef::Upvar(id, ..) | HirDef::Local(id) => {
let span = self.span_from_span(sub_span);
Some(Ref {
kind: RefKind::Variable,
span,
......@@ -719,20 +716,16 @@ fn fn_type(path: &ast::Path) -> bool {
HirDef::Const(..) |
HirDef::AssociatedConst(..) |
HirDef::VariantCtor(..) => {
let span = self.span_from_span(sub_span);
Some(Ref {
kind: RefKind::Variable,
span,
ref_id: id_from_def_id(def.def_id()),
})
}
HirDef::Trait(def_id) if fn_type(path) => {
// Function type bounds are desugared in the parser, so we have to
// special case them here.
let fn_span = path.segments.first().unwrap().ident.span;
HirDef::Trait(def_id) if fn_type(path_seg) => {
Some(Ref {
kind: RefKind::Type,
span: self.span_from_span(fn_span),
span,
ref_id: id_from_def_id(def_id),
})
}
......@@ -748,7 +741,6 @@ fn fn_type(path: &ast::Path) -> bool {
HirDef::Trait(def_id) |
HirDef::Existential(def_id) |
HirDef::TyParam(def_id) => {
let span = self.span_from_span(sub_span);
Some(Ref {
kind: RefKind::Type,
span,
......@@ -759,7 +751,6 @@ fn fn_type(path: &ast::Path) -> bool {
// This is a reference to a tuple struct where the def_id points
// to an invisible constructor function. That is not a very useful
// def, so adjust to point to the tuple struct itself.
let span = self.span_from_span(sub_span);
let parent_def_id = self.tcx.parent_def_id(def_id).unwrap();
Some(Ref {
kind: RefKind::Type,
......@@ -778,7 +769,6 @@ fn fn_type(path: &ast::Path) -> bool {
} else {
None
};
let span = self.span_from_span(sub_span);
Some(Ref {
kind: RefKind::Function,
span,
......@@ -786,7 +776,6 @@ fn fn_type(path: &ast::Path) -> bool {
})
}
HirDef::Fn(def_id) => {
let span = self.span_from_span(sub_span);
Some(Ref {
kind: RefKind::Function,
span,
......@@ -794,7 +783,6 @@ fn fn_type(path: &ast::Path) -> bool {
})
}
HirDef::Mod(def_id) => {
let span = self.span_from_span(sub_span);
Some(Ref {
kind: RefKind::Mod,
span,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册