X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_save_analysis%2Flib.rs;h=c4777393a9897dfb3ec0818f31d403eda0558b2a;hb=609d0bd8ac3f339697a0b036062ba7784ab41232;hp=1148daef8e39120f9b684c262e86ab7596815c56;hpb=32c1454a87e22431e79d189eaac6b89747460b50;p=rust.git diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 1148daef8e3..c4777393a98 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -60,9 +60,7 @@ 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 @@ pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option { 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 @@ pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option { 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { } 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { 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 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { 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| { @@ -367,7 +347,7 @@ pub fn get_item_data(&self, item: &ast::Item) -> Option { .as_ref() .and_then(|t| self.lookup_ref_id(t.ref_id)) .map(id_from_def_id) - .unwrap_or(null_id()), + .unwrap_or_else(|| null_id()), }, Impl { id: impl_id, @@ -402,15 +382,13 @@ pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option< 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 @@ pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option< // 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 @@ pub fn get_method_data(&self, id: ast::NodeId, name: ast::Name, span: Span) -> O 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 @@ pub fn get_method_data(&self, id: ast::NodeId, name: ast::Name, span: Span) -> O }, }; - 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 @@ pub fn get_trait_ref_data(&self, trait_ref: &ast::TraitRef) -> Option { 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 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { 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 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { 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 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { 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, @@ -632,7 +608,7 @@ pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { ref_id: def_id .or(decl_id) .map(|id| id_from_def_id(id)) - .unwrap_or(null_id()), + .unwrap_or_else(|| null_id()), })) } ast::ExprKind::Path(_, ref path) => { @@ -708,13 +684,14 @@ pub fn get_path_def(&self, id: NodeId) -> HirDef { } } - pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option { + pub fn get_path_data(&self, _id: NodeId, path: &ast::Path) -> Option { + path.segments.last().and_then(|seg| self.get_path_segment_data(seg)) + } + + pub fn get_path_segment_data(&self, path_seg: &ast::PathSegment) -> Option { // 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; } @@ -722,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, Some(sub_span), path.span, None); match def { HirDef::Upvar(id, ..) | HirDef::Local(id) => { - let span = self.span_from_span(sub_span); Some(Ref { kind: RefKind::Variable, span, @@ -743,23 +716,17 @@ 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 = 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), - } + HirDef::Trait(def_id) if fn_type(path_seg) => { + Some(Ref { + kind: RefKind::Type, + span, + ref_id: id_from_def_id(def_id), }) } HirDef::Struct(def_id) | @@ -774,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, @@ -785,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, @@ -804,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, @@ -812,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, @@ -820,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, @@ -844,10 +806,8 @@ pub fn get_field_ref_data( 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,