use rustc::hir::def::Def as HirDef;
use rustc::hir::def_id::DefId;
+use rustc::session::config::Input;
use rustc::ty::{self, TyCtxt};
use rustc_data_structures::fx::FxHashSet;
use std::path::Path;
+use std::env;
use syntax::ast::{self, Attribute, NodeId, PatKind, CRATE_NODE_ID};
use syntax::parse::token;
-use syntax::symbol::keywords;
use syntax::visit::{self, Visitor};
use syntax::print::pprust::{
bounds_to_string,
generic_params_to_string,
- path_to_string,
ty_to_string
};
use syntax::ptr::P;
-use syntax::codemap::{Spanned, DUMMY_SP, respan};
+use syntax::source_map::{Spanned, DUMMY_SP, respan};
use syntax_pos::*;
use {escape, generated_code, lower_attributes, PathCollector, SaveContext};
use span_utils::SpanUtils;
use sig;
-use rls_data::{CratePreludeData, Def, DefKind, GlobalCrateId, Import, ImportKind, Ref, RefKind,
- Relation, RelationKind, SpanData};
+use rls_data::{CompilationOptions, CratePreludeData, Def, DefKind, GlobalCrateId, Import,
+ ImportKind, Ref, RefKind, Relation, RelationKind, SpanData};
macro_rules! down_cast_data {
($id:ident, $kind:ident, $sp:expr) => {
// of macro use (callsite) spans. We store these to ensure
// we only write one macro def per unique macro definition, and
// one macro use per unique callsite span.
- // mac_defs: HashSet<Span>,
- macro_calls: FxHashSet<Span>,
+ // mac_defs: FxHashSet<Span>,
+ // macro_calls: FxHashSet<Span>,
}
impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
tcx: save_ctxt.tcx,
save_ctxt,
dumper,
- span: span_utils.clone(),
+ span: span_utils,
cur_scope: CRATE_NODE_ID,
- // mac_defs: HashSet::new(),
- macro_calls: FxHashSet(),
+ // mac_defs: FxHashSet::default(),
+ // macro_calls: FxHashSet::default(),
}
}
let crate_root = source_file.map(|source_file| {
let source_file = Path::new(source_file);
match source_file.file_name() {
- Some(_) => source_file.parent().unwrap().display().to_string(),
- None => source_file.display().to_string(),
- }
+ Some(_) => source_file.parent().unwrap().display(),
+ None => source_file.display(),
+ }.to_string()
});
let data = CratePreludeData {
.to_fingerprint()
.as_value(),
},
- crate_root: crate_root.unwrap_or("<no source>".to_owned()),
+ crate_root: crate_root.unwrap_or_else(|| "<no source>".to_owned()),
external_crates: self.save_ctxt.get_external_crates(),
span: self.span_from_span(krate.span),
};
self.dumper.crate_prelude(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 }..];
+ pub fn dump_compilation_options(&mut self, input: &Input, crate_name: &str) {
+ // Apply possible `remap-path-prefix` remapping to the input source file
+ // (and don't include remapping args anymore)
+ let (program, arguments) = {
+ let remap_arg_indices = {
+ let mut indices = FxHashSet::default();
+ // Args are guaranteed to be valid UTF-8 (checked early)
+ for (i, e) in env::args().enumerate() {
+ if e.starts_with("--remap-path-prefix=") {
+ indices.insert(i);
+ } else if e == "--remap-path-prefix" {
+ indices.insert(i);
+ indices.insert(i + 1);
+ }
+ }
+ indices
+ };
- let mut result = Vec::with_capacity(segments.len());
+ let mut args = env::args()
+ .enumerate()
+ .filter(|(i, _)| !remap_arg_indices.contains(i))
+ .map(|(_, arg)| {
+ match input {
+ Input::File(ref path) if path == Path::new(&arg) => {
+ let mapped = &self.tcx.sess.local_crate_source_file;
+ mapped
+ .as_ref()
+ .unwrap()
+ .to_string_lossy()
+ .into()
+ },
+ _ => arg,
+ }
+ });
- let mut segs = vec![];
- 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;
- }
+ (args.next().unwrap(), args.collect())
+ };
+
+ let data = CompilationOptions {
+ directory: self.tcx.sess.working_dir.0.clone(),
+ program,
+ arguments,
+ output: self.save_ctxt.compilation_output(crate_name),
+ };
- result
+ self.dumper.compilation_opts(data);
}
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);
+ }
}
}
self.visit_pat(&arg.pat);
let mut collector = PathCollector::new();
collector.visit_pat(&arg.pat);
- let span_utils = self.span.clone();
for (id, ident, ..) in collector.collected_idents {
let hir_id = self.tcx.hir.node_to_hir_id(id);
Some(s) => s.to_string(),
None => continue,
};
- let sub_span = span_utils.span_for_last_ident(ident.span);
- if !self.span.filter_generated(sub_span, ident.span) {
+ if !self.span.filter_generated(ident.span) {
let id = ::id_from_node_id(id, &self.save_ctxt);
- let span = self.span_from_span(sub_span.expect("No span found for variable"));
+ let span = self.span_from_span(ident.span);
self.dumper.dump_def(
&Access {
) {
debug!("process_method: {}:{}", id, ident);
- if let Some(mut method_data) = self.save_ctxt.get_method_data(id, ident.name, span) {
+ if let Some(mut method_data) = self.save_ctxt.get_method_data(id, ident, span) {
let sig_str = ::make_signature(&sig.decl, &generics);
if body.is_some() {
self.nest_tables(
);
}
- self.process_generic_params(&generics, span, &method_data.qualname, id);
+ self.process_generic_params(&generics, &method_data.qualname, id);
method_data.value = sig_str;
method_data.sig = sig::method_signature(id, ident, generics, sig, &self.save_ctxt);
fn process_generic_params(
&mut self,
generics: &'l ast::Generics,
- full_span: Span,
prefix: &str,
id: NodeId,
) {
let name = escape(self.span.snippet(param_ss));
// Append $id to name to make sure each one is unique.
let qualname = format!("{}::{}${}", prefix, name, id);
- if !self.span.filter_generated(Some(param_ss), full_span) {
+ if !self.span.filter_generated(param_ss) {
let id = ::id_from_node_id(param.id, &self.save_ctxt);
let span = self.span_from_span(param_ss);
item.id,
|v| v.process_formals(&decl.inputs, &fn_data.qualname),
);
- self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id);
+ self.process_generic_params(ty_params, &fn_data.qualname, item.id);
self.dumper.dump_def(&access_from!(self.save_ctxt, item), fn_data);
}
fn process_assoc_const(
&mut self,
id: ast::NodeId,
- name: ast::Name,
- span: Span,
+ ident: ast::Ident,
typ: &'l ast::Ty,
expr: Option<&'l ast::Expr>,
parent_id: DefId,
) {
let qualname = format!("::{}", self.tcx.node_path_str(id));
- let sub_span = self.span.sub_span_after_keyword(span, keywords::Const);
-
- if !self.span.filter_generated(sub_span, span) {
- let sig = sig::assoc_const_signature(id, name, typ, expr, &self.save_ctxt);
- let span = self.span_from_span(sub_span.expect("No span found for variable"));
+ if !self.span.filter_generated(ident.span) {
+ let sig = sig::assoc_const_signature(id, ident.name, typ, expr, &self.save_ctxt);
+ let span = self.span_from_span(ident.span);
self.dumper.dump_def(
&access_from!(self.save_ctxt, vis, id),
kind: DefKind::Const,
id: ::id_from_node_id(id, &self.save_ctxt),
span,
- name: name.to_string(),
+ name: ident.name.to_string(),
qualname,
value: ty_to_string(&typ),
parent: Some(::id_from_def_id(parent_id)),
let name = item.ident.to_string();
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
- let (kind, keyword) = match item.node {
- ast::ItemKind::Struct(_, _) => (DefKind::Struct, keywords::Struct),
- ast::ItemKind::Union(_, _) => (DefKind::Union, keywords::Union),
+ let kind = match item.node {
+ ast::ItemKind::Struct(_, _) => DefKind::Struct,
+ ast::ItemKind::Union(_, _) => DefKind::Union,
_ => unreachable!(),
};
- let sub_span = self.span.sub_span_after_keyword(item.span, keyword);
let (value, fields) = match item.node {
ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, _), _) |
ast::ItemKind::Union(ast::VariantData::Struct(ref fields, _), _) => {
_ => (String::new(), vec![]),
};
- if !self.span.filter_generated(sub_span, item.span) {
- let span = self.span_from_span(sub_span.expect("No span found for struct"));
+ if !self.span.filter_generated(item.ident.span) {
+ let span = self.span_from_span(item.ident.span);
self.dumper.dump_def(
&access_from!(self.save_ctxt, item),
Def {
self.visit_ty(&field.ty);
}
- self.process_generic_params(ty_params, item.span, &qualname, item.id);
+ self.process_generic_params(ty_params, &qualname, item.id);
}
fn process_enum(
for variant in &enum_definition.variants {
let name = variant.node.ident.name.to_string();
- let mut qualname = enum_data.qualname.clone();
- qualname.push_str("::");
- qualname.push_str(&name);
+ let qualname = format!("{}::{}", enum_data.qualname, name);
+ let name_span = variant.node.ident.span;
match variant.node.data {
ast::VariantData::Struct(ref fields, _) => {
- let sub_span = self.span.span_for_first_ident(variant.span);
let fields_str = fields
.iter()
.enumerate()
.map(|(i, f)| {
- f.ident.map(|i| i.to_string()).unwrap_or(i.to_string())
+ f.ident.map(|i| i.to_string()).unwrap_or_else(|| i.to_string())
})
.collect::<Vec<_>>()
.join(", ");
let value = format!("{}::{} {{ {} }}", enum_data.name, name, fields_str);
- if !self.span.filter_generated(sub_span, variant.span) {
- let span = self
- .span_from_span(sub_span.expect("No span found for struct variant"));
+ if !self.span.filter_generated(name_span) {
+ let span = self.span_from_span(name_span);
let id = ::id_from_node_id(variant.node.data.id(), &self.save_ctxt);
let parent = Some(::id_from_node_id(item.id, &self.save_ctxt));
}
}
ref v => {
- let sub_span = self.span.span_for_first_ident(variant.span);
let mut value = format!("{}::{}", enum_data.name, name);
if let &ast::VariantData::Tuple(ref fields, _) = v {
value.push('(');
.join(", "));
value.push(')');
}
- if !self.span.filter_generated(sub_span, variant.span) {
- let span =
- self.span_from_span(sub_span.expect("No span found for tuple variant"));
+ if !self.span.filter_generated(name_span) {
+ let span = self.span_from_span(name_span);
let id = ::id_from_node_id(variant.node.data.id(), &self.save_ctxt);
let parent = Some(::id_from_node_id(item.id, &self.save_ctxt));
self.visit_ty(&field.ty);
}
}
- self.process_generic_params(ty_params, item.span, &enum_data.qualname, item.id);
+ self.process_generic_params(ty_params, &enum_data.qualname, item.id);
self.dumper.dump_def(&access, enum_data);
}
if let &Some(ref trait_ref) = trait_ref {
self.process_path(trait_ref.ref_id, &trait_ref.path);
}
- self.process_generic_params(type_parameters, item.span, "", item.id);
+ self.process_generic_params(type_parameters, "", item.id);
for impl_item in impl_items {
let map = &self.tcx.hir;
self.process_impl_item(impl_item, map.local_def_id(item.id));
val.push_str(": ");
val.push_str(&bounds_to_string(trait_refs));
}
- let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait);
- if !self.span.filter_generated(sub_span, item.span) {
+ if !self.span.filter_generated(item.ident.span) {
let id = ::id_from_node_id(item.id, &self.save_ctxt);
- let span = self.span_from_span(sub_span.expect("No span found for trait"));
+ let span = self.span_from_span(item.ident.span);
let children = methods
.iter()
.map(|i| ::id_from_node_id(i.id, &self.save_ctxt))
let trait_ref = &trait_ref.trait_ref;
if let Some(id) = self.lookup_def_id(trait_ref.ref_id) {
- let sub_span = self.span.sub_span_for_type_name(trait_ref.path.span);
- if !self.span.filter_generated(sub_span, trait_ref.path.span) {
- let span = self.span_from_span(sub_span.expect("No span found for trait ref"));
+ let sub_span = trait_ref.path.segments.last().unwrap().ident.span;
+ if !self.span.filter_generated(sub_span) {
+ let span = self.span_from_span(sub_span);
self.dumper.dump_ref(Ref {
kind: RefKind::Type,
- span,
+ span: span.clone(),
ref_id: ::id_from_def_id(id),
});
- }
- if !self.span.filter_generated(sub_span, trait_ref.path.span) {
- let sub_span = self.span_from_span(sub_span.expect("No span for inheritance"));
self.dumper.dump_relation(Relation {
kind: RelationKind::SuperTrait,
- span: sub_span,
+ span,
from: ::id_from_def_id(id),
to: ::id_from_node_id(item.id, &self.save_ctxt),
});
}
// walk generics and methods
- self.process_generic_params(generics, item.span, &qualname, item.id);
+ self.process_generic_params(generics, &qualname, item.id);
for method in methods {
let map = &self.tcx.hir;
self.process_trait_item(method, map.local_def_id(item.id))
}
fn process_path(&mut self, id: NodeId, path: &'l ast::Path) {
- debug!("process_path {:?}", path);
- if generated_code(path.span) {
+ if self.span.filter_generated(path.span) {
return;
}
self.dump_path_ref(id, path);
if let Some(ref generic_args) = seg.args {
match **generic_args {
ast::GenericArgs::AngleBracketed(ref data) => {
- data.args.iter().for_each(|arg| match arg {
- ast::GenericArg::Type(ty) => self.visit_ty(ty),
- _ => {}
- });
+ for arg in &data.args {
+ match arg {
+ ast::GenericArg::Type(ty) => self.visit_ty(ty),
+ _ => {}
+ }
+ }
}
ast::GenericArgs::Parenthesized(ref data) => {
for t in &data.inputs {
}
}
- // 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(
variant: &'l ty::VariantDef,
base: &'l Option<P<ast::Expr>>,
) {
- self.write_sub_paths_truncated(path);
-
if let Some(struct_lit_data) = self.save_ctxt.get_expr_data(ex) {
+ self.write_sub_paths_truncated(path);
down_cast_data!(struct_lit_data, RefData, ex.span);
if !generated_code(ex.span) {
self.dumper.dump_ref(struct_lit_data);
// Explicit types in the turbo-fish.
if let Some(ref generic_args) = seg.args {
if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
- data.args.iter().for_each(|arg| match arg {
- ast::GenericArg::Type(ty) => self.visit_ty(ty),
- _ => {}
- });
+ for arg in &data.args {
+ match arg {
+ ast::GenericArg::Type(ty) => self.visit_ty(ty),
+ _ => {}
+ }
+ }
}
}
};
let variant = adt.variant_of_def(self.save_ctxt.get_path_def(p.id));
- for &Spanned { node: ref field, span } in fields {
- let sub_span = self.span.span_for_first_ident(span);
+ for &Spanned { node: ref field, .. } in fields {
if let Some(index) = self.tcx.find_field_index(field.ident, variant) {
- if !self.span.filter_generated(sub_span, span) {
- let span =
- self.span_from_span(sub_span.expect("No span fund for var ref"));
+ if !self.span.filter_generated(field.ident.span) {
+ let span = self.span_from_span(field.ident.span);
self.dumper.dump_ref(Ref {
kind: RefKind::Variable,
span,
match self.save_ctxt.get_path_def(id) {
HirDef::Local(id) => {
let mut value = if immut == ast::Mutability::Immutable {
- self.span.snippet(ident.span).to_string()
+ self.span.snippet(ident.span)
} else {
- "<mutable>".to_string()
+ "<mutable>".to_owned()
};
let hir_id = self.tcx.hir.node_to_hir_id(id);
let typ = self.save_ctxt
.tables
.node_id_to_type_opt(hir_id)
.map(|t| t.to_string())
- .unwrap_or(String::new());
+ .unwrap_or_default();
value.push_str(": ");
value.push_str(&typ);
- if !self.span.filter_generated(Some(ident.span), ident.span) {
+ if !self.span.filter_generated(ident.span) {
let qualname = format!("{}${}", ident.to_string(), id);
let id = ::id_from_node_id(id, &self.save_ctxt);
let span = self.span_from_span(ident.span);
None => String::new(),
};
- // Get the span only for the name of the variable (I hope the path
- // is only ever a variable name, but who knows?).
- let sub_span = self.span.span_for_last_ident(ident.span);
// Rust uses the id of the pattern for var lookups, so we'll use it too.
- if !self.span.filter_generated(sub_span, ident.span) {
+ if !self.span.filter_generated(ident.span) {
let qualname = format!("{}${}", ident.to_string(), id);
let id = ::id_from_node_id(id, &self.save_ctxt);
- let span = self.span_from_span(sub_span.expect("No span found for variable"));
+ let span = self.span_from_span(ident.span);
self.dumper.dump_def(
&Access {
/// If the span is not macro-generated, do nothing, else use callee and
/// callsite spans to record macro definition and use data, using the
/// mac_uses and mac_defs sets to prevent multiples.
- fn process_macro_use(&mut self, span: Span) {
- let source_span = span.source_callsite();
- if self.macro_calls.contains(&source_span) {
- return;
- }
- self.macro_calls.insert(source_span);
+ fn process_macro_use(&mut self, _span: Span) {
+ // FIXME if we're not dumping the defs (see below), there is no point
+ // dumping refs either.
+ // let source_span = span.source_callsite();
+ // if !self.macro_calls.insert(source_span) {
+ // return;
+ // }
- let data = match self.save_ctxt.get_macro_use_data(span) {
- None => return,
- Some(data) => data,
- };
+ // let data = match self.save_ctxt.get_macro_use_data(span) {
+ // None => return,
+ // Some(data) => data,
+ // };
- self.dumper.macro_use(data);
+ // self.dumper.macro_use(data);
// FIXME write the macro def
// let mut hasher = DefaultHasher::new();
ast::TraitItemKind::Const(ref ty, ref expr) => {
self.process_assoc_const(
trait_item.id,
- trait_item.ident.name,
- trait_item.span,
+ trait_item.ident,
&ty,
expr.as_ref().map(|e| &**e),
trait_id,
// FIXME do something with _bounds (for type refs)
let name = trait_item.ident.name.to_string();
let qualname = format!("::{}", self.tcx.node_path_str(trait_item.id));
- let sub_span = self.span
- .sub_span_after_keyword(trait_item.span, keywords::Type);
- if !self.span.filter_generated(sub_span, trait_item.span) {
- let span = self.span_from_span(sub_span.expect("No span found for assoc type"));
+ if !self.span.filter_generated(trait_item.ident.span) {
+ let span = self.span_from_span(trait_item.ident.span);
let id = ::id_from_node_id(trait_item.id, &self.save_ctxt);
self.dumper.dump_def(
ast::ImplItemKind::Const(ref ty, ref expr) => {
self.process_assoc_const(
impl_item.id,
- impl_item.ident.name,
- impl_item.span,
+ impl_item.ident,
&ty,
Some(expr),
impl_id,
.map(::id_from_def_id);
match use_tree.kind {
- ast::UseTreeKind::Simple(..) => {
+ ast::UseTreeKind::Simple(alias, ..) => {
let ident = use_tree.ident();
let path = ast::Path {
segments: prefix.segments
span: path.span,
};
- let sub_span = self.span.span_for_last_ident(path.span);
- let alias_span = self.span.sub_span_after_keyword(use_tree.span, keywords::As);
- let ref_id = self.lookup_def_id(id);
-
- if !self.span.filter_generated(sub_span, path.span) {
- let span = self.span_from_span(sub_span.expect("No span found for use"));
- let alias_span = alias_span.map(|sp| self.span_from_span(sp));
+ let sub_span = path.segments.last().unwrap().ident.span;
+ if !self.span.filter_generated(sub_span) {
+ let ref_id = self.lookup_def_id(id).map(|id| ::id_from_def_id(id));
+ let alias_span = alias.map(|i| self.span_from_span(i.span));
+ let span = self.span_from_span(sub_span);
self.dumper.import(&access, Import {
kind: ImportKind::Use,
- ref_id: ref_id.map(|id| ::id_from_def_id(id)),
+ ref_id,
span,
alias_span,
name: ident.to_string(),
value: String::new(),
parent,
});
+ self.write_sub_paths_truncated(&path);
}
- self.write_sub_paths_truncated(&path);
}
ast::UseTreeKind::Glob => {
let path = ast::Path {
Vec::new()
};
- let sub_span = self.span.sub_span_of_token(use_tree.span,
- token::BinOp(token::Star));
- if !self.span.filter_generated(sub_span, use_tree.span) {
+ let sub_span =
+ self.span.sub_span_of_token(use_tree.span, token::BinOp(token::Star));
+ if !self.span.filter_generated(use_tree.span) {
let span =
self.span_from_span(sub_span.expect("No span found for use glob"));
self.dumper.import(&access, Import {
value: names.join(", "),
parent,
});
+ self.write_sub_paths(&path);
}
- self.write_sub_paths(&path);
}
ast::UseTreeKind::Nested(ref nested_items) => {
let prefix = ast::Path {
}
}
}
+
+ fn process_bounds(&mut self, bounds: &'l ast::GenericBounds) {
+ for bound in bounds {
+ if let ast::GenericBound::Trait(ref trait_ref, _) = *bound {
+ self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
+ }
+ }
+ }
}
impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll, O> {
let qualname = format!("::{}", self.tcx.node_path_str(id));
- let cm = self.tcx.sess.codemap();
+ let cm = self.tcx.sess.source_map();
let filename = cm.span_to_filename(span);
let data_id = ::id_from_node_id(id, &self.save_ctxt);
let children = m.items
self.process_use_tree(use_tree, item.id, item, &prefix);
}
ExternCrate(_) => {
- let alias_span = self.span.span_for_last_ident(item.span);
-
- if !self.span.filter_generated(alias_span, item.span) {
- let span =
- self.span_from_span(alias_span.expect("No span found for extern crate"));
+ let name_span = item.ident.span;
+ if !self.span.filter_generated(name_span) {
+ let span = self.span_from_span(name_span);
let parent = self.save_ctxt.tcx.hir.opt_local_def_id(item.id)
.and_then(|id| self.save_ctxt.tcx.parent_def_id(id))
.map(::id_from_def_id);
Ty(ref ty, ref ty_params) => {
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
let value = ty_to_string(&ty);
- let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type);
- if !self.span.filter_generated(sub_span, item.span) {
- let span = self.span_from_span(sub_span.expect("No span found for typedef"));
+ if !self.span.filter_generated(item.ident.span) {
+ let span = self.span_from_span(item.ident.span);
let id = ::id_from_node_id(item.id, &self.save_ctxt);
self.dumper.dump_def(
}
self.visit_ty(&ty);
- self.process_generic_params(ty_params, item.span, &qualname, item.id);
+ self.process_generic_params(ty_params, &qualname, item.id);
}
Existential(ref _bounds, ref ty_params) => {
let qualname = format!("::{}", self.tcx.node_path_str(item.id));
// FIXME do something with _bounds
let value = String::new();
- let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type);
- if !self.span.filter_generated(sub_span, item.span) {
- let span = self.span_from_span(sub_span.expect("No span found for typedef"));
+ if !self.span.filter_generated(item.ident.span) {
+ let span = self.span_from_span(item.ident.span);
let id = ::id_from_node_id(item.id, &self.save_ctxt);
self.dumper.dump_def(
);
}
- self.process_generic_params(ty_params, item.span, &qualname, item.id);
+ self.process_generic_params(ty_params, &qualname, item.id);
}
Mac(_) => (),
_ => visit::walk_item(self, item),
}
fn visit_generics(&mut self, generics: &'l ast::Generics) {
- generics.params.iter().for_each(|param| match param.kind {
- ast::GenericParamKind::Lifetime { .. } => {}
- ast::GenericParamKind::Type { ref default, .. } => {
- for bound in ¶m.bounds {
- if let ast::GenericBound::Trait(ref trait_ref, _) = *bound {
- self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
- }
- }
+ for param in &generics.params {
+ if let ast::GenericParamKind::Type { ref default, .. } = param.kind {
+ self.process_bounds(¶m.bounds);
if let Some(ref ty) = default {
self.visit_ty(&ty);
}
}
- });
+ }
+ for pred in &generics.where_clause.predicates {
+ if let ast::WherePredicate::BoundPredicate(ref wbp) = *pred {
+ self.process_bounds(&wbp.bounds);
+ self.visit_ty(&wbp.bounded_ty);
+ }
+ }
}
fn visit_ty(&mut self, t: &'l ast::Ty) {
}
if let Some(id) = self.lookup_def_id(t.id) {
- if let Some(sub_span) = self.span.sub_span_for_type_name(t.span) {
- let span = self.span_from_span(sub_span);
- self.dumper.dump_ref(Ref {
- kind: RefKind::Type,
- span,
- ref_id: ::id_from_def_id(id),
- });
- }
+ let sub_span = path.segments.last().unwrap().ident.span;
+ let span = self.span_from_span(sub_span);
+ self.dumper.dump_ref(Ref {
+ kind: RefKind::Type,
+ span,
+ ref_id: ::id_from_def_id(id),
+ });
}
self.write_sub_paths_truncated(path);
}
}
ast::ExprKind::Closure(_, _, _, ref decl, ref body, _fn_decl_span) => {
- let mut id = String::from("$");
- id.push_str(&ex.id.to_string());
+ let id = format!("${}", ex.id);
// walk arg and return types
for arg in &decl.inputs {
fn visit_arm(&mut self, arm: &'l ast::Arm) {
self.process_var_decl_multi(&arm.pats);
- walk_list!(self, visit_expr, &arm.guard);
+ match arm.guard {
+ Some(ast::Guard::If(ref expr)) => self.visit_expr(expr),
+ _ => {}
+ }
self.visit_expr(&arm.body);
}
let value = l.init
.as_ref()
.map(|i| self.span.snippet(i.span))
- .unwrap_or(String::new());
+ .unwrap_or_default();
self.process_var_decl(&l.pat, value);
// Just walk the initialiser and type (don't want to walk the pattern again).
if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) {
down_cast_data!(fn_data, DefData, item.span);
- self.nest_tables(
- item.id,
- |v| v.process_formals(&decl.inputs, &fn_data.qualname),
- );
- self.process_generic_params(generics, item.span, &fn_data.qualname, item.id);
+ self.process_generic_params(generics, &fn_data.qualname, item.id);
self.dumper.dump_def(&access, fn_data);
}