From c2bb7cadf24e82b80f403c09e800fe5fad504caf Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Mon, 10 Sep 2018 12:54:36 +1200 Subject: [PATCH] save-analysis: remove hacky, unnecessary code now that we have spans for every ident --- src/librustc_save_analysis/dump_visitor.rs | 169 ++++++++----------- src/librustc_save_analysis/lib.rs | 116 +++++-------- src/librustc_save_analysis/span_utils.rs | 184 ++------------------- 3 files changed, 124 insertions(+), 345 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 97bdb9e5fa30c..d05f37cc0a125 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -34,7 +34,6 @@ 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, @@ -323,7 +322,6 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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); @@ -331,10 +329,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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 { @@ -373,7 +370,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ) { 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( @@ -382,7 +379,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ); } - 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); @@ -415,7 +412,6 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn process_generic_params( &mut self, generics: &'l ast::Generics, - full_span: Span, prefix: &str, id: NodeId, ) { @@ -427,7 +423,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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); @@ -471,7 +467,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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); } @@ -505,8 +501,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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, @@ -515,11 +510,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ) { 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), @@ -527,7 +520,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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)), @@ -558,13 +551,12 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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, _), _) => { @@ -595,8 +587,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { _ => (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 { @@ -621,7 +613,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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( @@ -642,10 +634,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { for variant in &enum_definition.variants { let name = variant.node.ident.name.to_string(); 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() @@ -655,9 +647,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { .collect::>() .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)); @@ -684,7 +675,6 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { } } 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('('); @@ -695,9 +685,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { .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)); @@ -731,7 +720,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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); } @@ -755,7 +744,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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)); @@ -779,10 +768,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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)) @@ -815,21 +803,18 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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), }); @@ -838,7 +823,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { } // 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)) @@ -988,12 +973,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { }; 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, @@ -1034,7 +1017,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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); @@ -1109,14 +1092,11 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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 { @@ -1190,8 +1170,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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, @@ -1214,11 +1193,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // 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( @@ -1263,8 +1240,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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, @@ -1328,7 +1304,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { .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 @@ -1339,16 +1315,14 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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(), @@ -1377,9 +1351,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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 { @@ -1471,11 +1445,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc 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); @@ -1518,9 +1490,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc 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( @@ -1543,15 +1514,14 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc } 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( @@ -1573,7 +1543,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc ); } - 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), @@ -1606,14 +1576,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc } 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); @@ -1757,7 +1726,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc 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); } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 4b43a1a6270f8..991172370148e 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -60,9 +60,7 @@ use std::path::{Path, PathBuf}; use syntax::ast::{self, Attribute, NodeId, PatKind}; use syntax::source_map::Spanned; use syntax::parse::lexer::comments::strip_doc_comment_decoration; -use syntax::parse::token; use syntax::print::pprust; -use syntax::symbol::keywords; use syntax::visit::{self, Visitor}; use syntax::print::pprust::{arg_to_string, ty_to_string}; use syntax::source_map::MacroAttribute; @@ -162,14 +160,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); match item.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { - let sub_span = self.span_utils - .sub_span_after_keyword(item.span, keywords::Fn); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { kind: DefKind::ForeignFunction, id: id_from_node_id(item.id, self), - span: self.span_from_span(sub_span.unwrap()), + span: self.span_from_span(item.ident.span), name: item.ident.to_string(), qualname, value: make_signature(decl, generics), @@ -181,13 +177,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ForeignItemKind::Static(ref ty, m) => { - let keyword = if m { keywords::Mut } else { keywords::Static }; - let sub_span = self.span_utils.sub_span_after_keyword(item.span, keyword); - filter!(self.span_utils, sub_span, item.span, None); + ast::ForeignItemKind::Static(ref ty, _) => { + filter!(self.span_utils, item.ident.span); let id = ::id_from_node_id(item.id, self); - let span = self.span_from_span(sub_span.unwrap()); + let span = self.span_from_span(item.ident.span); Some(Data::DefData(Def { kind: DefKind::ForeignStatic, @@ -214,13 +208,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { match item.node { ast::ItemKind::Fn(ref decl, .., ref generics, _) => { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); - let sub_span = self.span_utils - .sub_span_after_keyword(item.span, keywords::Fn); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { kind: DefKind::Function, id: id_from_node_id(item.id, self), - span: self.span_from_span(sub_span.unwrap()), + span: self.span_from_span(item.ident.span), name: item.ident.to_string(), qualname, value: make_signature(decl, generics), @@ -232,19 +224,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ItemKind::Static(ref typ, mt, _) => { + ast::ItemKind::Static(ref typ, ..) => { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); - let keyword = match mt { - ast::Mutability::Mutable => keywords::Mut, - ast::Mutability::Immutable => keywords::Static, - }; - - let sub_span = self.span_utils.sub_span_after_keyword(item.span, keyword); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); let id = id_from_node_id(item.id, self); - let span = self.span_from_span(sub_span.unwrap()); + let span = self.span_from_span(item.ident.span); Some(Data::DefData(Def { kind: DefKind::Static, @@ -263,12 +249,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } ast::ItemKind::Const(ref typ, _) => { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); - let sub_span = self.span_utils - .sub_span_after_keyword(item.span, keywords::Const); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); let id = id_from_node_id(item.id, self); - let span = self.span_from_span(sub_span.unwrap()); + let span = self.span_from_span(item.ident.span); Some(Data::DefData(Def { kind: DefKind::Const, @@ -291,16 +275,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let cm = self.tcx.sess.source_map(); let filename = cm.span_to_filename(m.inner); - let sub_span = self.span_utils - .sub_span_after_keyword(item.span, keywords::Mod); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { kind: DefKind::Mod, id: id_from_node_id(item.id, self), name: item.ident.to_string(), qualname, - span: self.span_from_span(sub_span.unwrap()), + span: self.span_from_span(item.ident.span), value: filename.to_string(), parent: None, children: m.items @@ -316,9 +298,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ast::ItemKind::Enum(ref def, _) => { let name = item.ident.to_string(); let qualname = format!("::{}", self.tcx.node_path_str(item.id)); - let sub_span = self.span_utils - .sub_span_after_keyword(item.span, keywords::Enum); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); let variants_str = def.variants .iter() .map(|v| v.node.ident.to_string()) @@ -328,7 +308,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { Some(Data::DefData(Def { kind: DefKind::Enum, id: id_from_node_id(item.id, self), - span: self.span_from_span(sub_span.unwrap()), + span: self.span_from_span(item.ident.span), name, qualname, value, @@ -349,11 +329,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { if generated_code(path.span) { return None; } - let sub_span = self.span_utils.sub_span_for_type_name(path.span); - filter!(self.span_utils, sub_span, typ.span, None); + let sub_span = path.segments.last().unwrap().ident.span; + filter!(self.span_utils, sub_span); let impl_id = self.next_impl_id(); - let span = self.span_from_span(sub_span.unwrap()); + let span = self.span_from_span(sub_span); let type_data = self.lookup_ref_id(typ.id); type_data.map(|type_data| { @@ -402,15 +382,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { if let Some(ident) = field.ident { let name = ident.to_string(); let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident); - let sub_span = self.span_utils - .sub_span_before_token(field.span, token::Colon); - filter!(self.span_utils, sub_span, field.span, None); + filter!(self.span_utils, ident.span); let def_id = self.tcx.hir.local_def_id(field.id); let typ = self.tcx.type_of(def_id).to_string(); let id = id_from_node_id(field.id, self); - let span = self.span_from_span(sub_span.unwrap()); + let span = self.span_from_span(ident.span); Some(Def { kind: DefKind::Field, @@ -433,7 +411,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { // 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. - pub fn get_method_data(&self, id: ast::NodeId, name: ast::Name, span: Span) -> Option { + pub fn get_method_data(&self, id: ast::NodeId, ident: ast::Ident, span: Span) -> Option { // 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, parent_scope, decl_id, docs, attributes) = @@ -459,7 +437,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { qualname.push_str(&self.tcx.item_path_str(def_id)); self.tcx .associated_items(def_id) - .find(|item| item.ident.name == name) + .find(|item| item.ident.name == ident.name) .map(|item| decl_id = Some(item.def_id)); } qualname.push_str(">"); @@ -512,16 +490,15 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { }, }; - let qualname = format!("{}::{}", qualname, name); + let qualname = format!("{}::{}", qualname, ident.name); - let sub_span = self.span_utils.sub_span_after_keyword(span, keywords::Fn); - filter!(self.span_utils, sub_span, span, None); + filter!(self.span_utils, ident.span); Some(Def { kind: DefKind::Method, id: id_from_node_id(id, self), - span: self.span_from_span(sub_span.unwrap()), - name: name.to_string(), + span: self.span_from_span(ident.span), + name: ident.name.to_string(), qualname, // FIXME you get better data here by using the visitor. value: String::new(), @@ -540,9 +517,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { if generated_code(span) { return None; } - let sub_span = self.span_utils.sub_span_for_type_name(span).or(Some(span)); - filter!(self.span_utils, sub_span, span, None); - let span = self.span_from_span(sub_span.unwrap()); + let sub_span = trait_ref.path.segments.last().unwrap().ident.span; + filter!(self.span_utils, sub_span); + let span = self.span_from_span(sub_span); Some(Ref { kind: RefKind::Type, span, @@ -574,9 +551,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ty::Adt(def, _) if !def.is_enum() => { let variant = &def.non_enum_variant(); let index = self.tcx.find_field_index(ident, variant).unwrap(); - let sub_span = self.span_utils.span_for_last_ident(expr.span); - filter!(self.span_utils, sub_span, expr.span, None); - let span = self.span_from_span(sub_span.unwrap()); + filter!(self.span_utils, ident.span); + let span = self.span_from_span(ident.span); return Some(Data::RefData(Ref { kind: RefKind::Variable, span, @@ -593,9 +569,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ast::ExprKind::Struct(ref path, ..) => { match self.tables.expr_ty_adjusted(&hir_node).sty { ty::Adt(def, _) if !def.is_enum() => { - let sub_span = self.span_utils.span_for_last_ident(path.span); - filter!(self.span_utils, sub_span, path.span, None); - let span = self.span_from_span(sub_span.unwrap()); + let sub_span = path.segments.last().unwrap().ident.span; + filter!(self.span_utils, sub_span); + let span = self.span_from_span(sub_span); Some(Data::RefData(Ref { kind: RefKind::Type, span, @@ -624,7 +600,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ty::TraitContainer(_) => (None, Some(method_id)), }; let sub_span = seg.ident.span; - filter!(self.span_utils, Some(sub_span), expr.span, None); + filter!(self.span_utils, sub_span); let span = self.span_from_span(sub_span); Some(Data::RefData(Ref { kind: RefKind::Function, @@ -729,7 +705,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { 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, Some(sub_span), path.span, None); + filter!(self.span_utils, sub_span); match def { HirDef::Upvar(id, ..) | HirDef::Local(id) => { let span = self.span_from_span(sub_span); @@ -753,13 +729,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { 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 = self.span_utils.span_for_first_ident(path.span); - fn_span.map(|span| { - Ref { - kind: RefKind::Type, - span: self.span_from_span(span), - ref_id: id_from_def_id(def_id), - } + let fn_span = path.segments.first().unwrap().ident.span; + Some(Ref { + kind: RefKind::Type, + span: self.span_from_span(fn_span), + ref_id: id_from_def_id(def_id), }) } HirDef::Struct(def_id) | @@ -844,10 +818,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { variant: &ty::VariantDef, ) -> Option { let index = self.tcx.find_field_index(field_ref.ident, variant).unwrap(); - // We don't really need a sub-span here, but no harm done - let sub_span = self.span_utils.span_for_last_ident(field_ref.ident.span); - filter!(self.span_utils, sub_span, field_ref.ident.span, None); - let span = self.span_from_span(sub_span.unwrap()); + filter!(self.span_utils, field_ref.ident.span); + let span = self.span_from_span(field_ref.ident.span); Some(Ref { kind: RefKind::Variable, span, diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index 47677a751712e..902353da13f76 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -16,7 +16,6 @@ use std::cell::Cell; use syntax::parse::lexer::{self, StringReader}; use syntax::parse::token::{self, Token}; -use syntax::symbol::keywords; use syntax_pos::*; #[derive(Clone)] @@ -67,131 +66,6 @@ impl<'a> SpanUtils<'a> { lexer::StringReader::retokenize(&self.sess.parse_sess, span) } - // Re-parses a path and returns the span for the last identifier in the path - pub fn span_for_last_ident(&self, span: Span) -> Option { - let mut result = None; - - let mut toks = self.retokenise_span(span); - let mut bracket_count = 0; - loop { - let ts = toks.real_token(); - if ts.tok == token::Eof { - return result; - } - if bracket_count == 0 && (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) { - result = Some(ts.sp); - } - - bracket_count += match ts.tok { - token::Lt => 1, - token::Gt => -1, - token::BinOp(token::Shr) => -2, - _ => 0, - } - } - } - - // Return the span for the first identifier in the path. - pub fn span_for_first_ident(&self, span: Span) -> Option { - let mut toks = self.retokenise_span(span); - let mut bracket_count = 0; - loop { - let ts = toks.real_token(); - if ts.tok == token::Eof { - return None; - } - if bracket_count == 0 && (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) { - return Some(ts.sp); - } - - bracket_count += match ts.tok { - token::Lt => 1, - token::Gt => -1, - token::BinOp(token::Shr) => -2, - _ => 0, - } - } - } - - // Return the span for the last ident before a `<` and outside any - // angle brackets, or the last span. - pub fn sub_span_for_type_name(&self, span: Span) -> Option { - let mut toks = self.retokenise_span(span); - let mut prev = toks.real_token(); - let mut result = None; - - // We keep track of the following two counts - the depth of nesting of - // angle brackets, and the depth of nesting of square brackets. For the - // angle bracket count, we only count tokens which occur outside of any - // square brackets (i.e. bracket_count == 0). The intuition here is - // that we want to count angle brackets in the type, but not any which - // could be in expression context (because these could mean 'less than', - // etc.). - let mut angle_count = 0; - let mut bracket_count = 0; - loop { - let next = toks.real_token(); - - if (next.tok == token::Lt || next.tok == token::Colon) && angle_count == 0 - && bracket_count == 0 && prev.tok.is_ident() - { - result = Some(prev.sp); - } - - if bracket_count == 0 { - angle_count += match prev.tok { - token::Lt => 1, - token::Gt => -1, - token::BinOp(token::Shl) => 2, - token::BinOp(token::Shr) => -2, - _ => 0, - }; - } - - bracket_count += match prev.tok { - token::OpenDelim(token::Bracket) => 1, - token::CloseDelim(token::Bracket) => -1, - _ => 0, - }; - - if next.tok == token::Eof { - break; - } - prev = next; - } - #[cfg(debug_assertions)] { - if angle_count != 0 || bracket_count != 0 { - let loc = self.sess.source_map().lookup_char_pos(span.lo()); - span_bug!( - span, - "Mis-counted brackets when breaking path? Parsing '{}' in {}, line {}", - self.snippet(span), - loc.file.name, - loc.line - ); - } - } - if result.is_none() && prev.tok.is_ident() { - return Some(prev.sp); - } - result - } - - pub fn sub_span_before_token(&self, span: Span, tok: Token) -> Option { - let mut toks = self.retokenise_span(span); - let mut prev = toks.real_token(); - loop { - if prev.tok == token::Eof { - return None; - } - let next = toks.real_token(); - if next.tok == tok { - return Some(prev.sp); - } - prev = next; - } - } - pub fn sub_span_of_token(&self, span: Span, tok: Token) -> Option { let mut toks = self.retokenise_span(span); loop { @@ -205,28 +79,6 @@ impl<'a> SpanUtils<'a> { } } - pub fn sub_span_after_keyword(&self, span: Span, keyword: keywords::Keyword) -> Option { - self.sub_span_after(span, |t| t.is_keyword(keyword)) - } - - fn sub_span_after bool>(&self, span: Span, f: F) -> Option { - let mut toks = self.retokenise_span(span); - loop { - let ts = toks.real_token(); - if ts.tok == token::Eof { - return None; - } - if f(ts.tok) { - let ts = toks.real_token(); - if ts.tok == token::Eof { - return None; - } else { - return Some(ts.sp); - } - } - } - } - // // Return the name for a macro definition (identifier after first `!`) // pub fn span_for_macro_def_name(&self, span: Span) -> Option { // let mut toks = self.retokenise_span(span); @@ -271,42 +123,28 @@ impl<'a> SpanUtils<'a> { /// /// Used to filter out spans of minimal value, /// such as references to macro internal variables. - pub fn filter_generated(&self, sub_span: Option, parent: Span) -> bool { - if !generated_code(parent) { - // Edge case - this occurs on generated code with incorrect expansion info. - return sub_span.is_none() + pub fn filter_generated(&self, span: Span) -> bool { + if span.is_dummy() { + return true; + } + + if !generated_code(span) { + return false; } - // If sub_span is none, filter out generated code. - let sub_span = match sub_span { - Some(ss) => ss, - None => return true, - }; //If the span comes from a fake source_file, filter it. - if !self.sess + !self.sess .source_map() - .lookup_char_pos(parent.lo()) + .lookup_char_pos(span.lo()) .file .is_real_file() - { - return true; - } - - // Otherwise, a generated span is deemed invalid if it is not a sub-span of the root - // callsite. This filters out macro internal variables and most malformed spans. - !parent.source_callsite().contains(sub_span) } } macro_rules! filter { - ($util: expr, $span: expr, $parent: expr, None) => { - if $util.filter_generated($span, $parent) { + ($util: expr, $parent: expr) => { + if $util.filter_generated($parent) { return None; } }; - ($util: expr, $span: ident, $parent: expr) => { - if $util.filter_generated($span, $parent) { - return; - } - }; }