From a07c9a20b721554d23c45499a753bf4fdfdc7474 Mon Sep 17 00:00:00 2001 From: Jonas Bushart Date: Tue, 14 Feb 2017 11:05:53 +0100 Subject: [PATCH 1/3] Export attributes in save-analysis data Some annotations like the "test" annotations might be of interest for other projects, especially rls. Export all attributes in a new attributes item. --- src/librustc_save_analysis/data.rs | 12 +- src/librustc_save_analysis/dump_visitor.rs | 14 ++- src/librustc_save_analysis/external_data.rs | 118 +++++++++++++++++++- src/librustc_save_analysis/json_dumper.rs | 12 ++ src/librustc_save_analysis/lib.rs | 21 +++- 5 files changed, 171 insertions(+), 6 deletions(-) diff --git a/src/librustc_save_analysis/data.rs b/src/librustc_save_analysis/data.rs index 0a6281bf8c54c..6caf81380e40d 100644 --- a/src/librustc_save_analysis/data.rs +++ b/src/librustc_save_analysis/data.rs @@ -15,7 +15,7 @@ use rustc::hir; use rustc::hir::def_id::{CrateNum, DefId}; -use syntax::ast::{self, NodeId}; +use syntax::ast::{self, Attribute, NodeId}; use syntax_pos::Span; pub struct CrateData { @@ -136,6 +136,7 @@ pub struct EnumData { pub visibility: Visibility, pub docs: String, pub sig: Signature, + pub attributes: Vec, } /// Data for extern crates. @@ -171,6 +172,7 @@ pub struct FunctionData { pub parent: Option, pub docs: String, pub sig: Signature, + pub attributes: Vec, } /// Data about a function call. @@ -256,6 +258,7 @@ pub struct MethodData { pub visibility: Visibility, pub docs: String, pub sig: Signature, + pub attributes: Vec, } /// Data for modules. @@ -271,6 +274,7 @@ pub struct ModData { pub visibility: Visibility, pub docs: String, pub sig: Signature, + pub attributes: Vec, } /// Data for a reference to a module. @@ -295,6 +299,7 @@ pub struct StructData { pub visibility: Visibility, pub docs: String, pub sig: Signature, + pub attributes: Vec, } #[derive(Debug, RustcEncodable)] @@ -309,6 +314,7 @@ pub struct StructVariantData { pub parent: Option, pub docs: String, pub sig: Signature, + pub attributes: Vec, } #[derive(Debug, RustcEncodable)] @@ -323,6 +329,7 @@ pub struct TraitData { pub visibility: Visibility, pub docs: String, pub sig: Signature, + pub attributes: Vec, } #[derive(Debug, RustcEncodable)] @@ -337,6 +344,7 @@ pub struct TupleVariantData { pub parent: Option, pub docs: String, pub sig: Signature, + pub attributes: Vec, } /// Data for a typedef. @@ -351,6 +359,7 @@ pub struct TypeDefData { pub parent: Option, pub docs: String, pub sig: Option, + pub attributes: Vec, } /// Data for a reference to a type or trait. @@ -396,6 +405,7 @@ pub struct VariableData { pub visibility: Visibility, pub docs: String, pub sig: Option, + pub attributes: Vec, } #[derive(Debug, RustcEncodable)] diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 3c275e0996dac..54069775418ce 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -47,7 +47,8 @@ use syntax::ptr::P; use syntax::codemap::Spanned; use syntax_pos::*; -use super::{escape, generated_code, SaveContext, PathCollector, docs_for_attrs}; +use super::{escape, generated_code, SaveContext, PathCollector, docs_for_attrs, + remove_docs_from_attrs}; use super::data::*; use super::dump::Dump; use super::external_data::{Lower, make_def_id}; @@ -373,6 +374,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { visibility: Visibility::Inherited, docs: String::new(), sig: None, + attributes: vec![], }.lower(self.tcx)); } } @@ -448,6 +450,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { visibility: vis, docs: docs_for_attrs(attrs), sig: method_data.sig, + attributes: remove_docs_from_attrs(attrs), }.lower(self.tcx)); } @@ -519,6 +522,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { parent: None, docs: String::new(), sig: None, + attributes: vec![], }.lower(self.tcx)); } } @@ -592,6 +596,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { visibility: vis, docs: docs_for_attrs(attrs), sig: None, + attributes: remove_docs_from_attrs(attrs), }.lower(self.tcx)); } @@ -636,6 +641,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: self.save_ctxt.sig_base(item), + attributes: remove_docs_from_attrs(&item.attrs), }.lower(self.tcx)); } @@ -701,6 +707,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { parent: Some(make_def_id(item.id, &self.tcx.hir)), docs: docs_for_attrs(&variant.node.attrs), sig: sig, + attributes: remove_docs_from_attrs(&variant.node.attrs), }.lower(self.tcx)); } } @@ -727,6 +734,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { parent: Some(make_def_id(item.id, &self.tcx.hir)), docs: docs_for_attrs(&variant.node.attrs), sig: sig, + attributes: remove_docs_from_attrs(&variant.node.attrs), }.lower(self.tcx)); } } @@ -798,6 +806,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: self.save_ctxt.sig_base(item), + attributes: remove_docs_from_attrs(&item.attrs), }.lower(self.tcx)); } @@ -1064,6 +1073,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { visibility: Visibility::Inherited, docs: String::new(), sig: None, + attributes: vec![], }.lower(self.tcx)); } } @@ -1305,6 +1315,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll, parent: None, docs: docs_for_attrs(&item.attrs), sig: Some(self.save_ctxt.sig_base(item)), + attributes: remove_docs_from_attrs(&item.attrs), }.lower(self.tcx)); } @@ -1527,6 +1538,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll, visibility: Visibility::Inherited, docs: String::new(), sig: None, + attributes: vec![], }.lower(self.tcx)); } } diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs index fccb56e88b3de..0cfa71a349916 100644 --- a/src/librustc_save_analysis/external_data.rs +++ b/src/librustc_save_analysis/external_data.rs @@ -11,7 +11,7 @@ use rustc::hir::def_id::{CrateNum, DefId, DefIndex}; use rustc::hir::map::Map; use rustc::ty::TyCtxt; -use syntax::ast::NodeId; +use syntax::ast::{self, LitKind, NodeId, StrStyle}; use syntax::codemap::CodeMap; use syntax_pos::Span; @@ -64,6 +64,102 @@ impl SpanData { } } +/// Represent an arbitrary attribute on a code element +#[derive(Clone, Debug, RustcEncodable)] +pub struct Attribute { + value: AttributeItem, + span: SpanData, +} + +impl Lower for ast::Attribute { + type Target = Attribute; + + fn lower(self, tcx: TyCtxt) -> Attribute { + Attribute { + value: self.value.lower(tcx), + span: SpanData::from_span(self.span, tcx.sess.codemap()), + } + } +} + +impl Lower for Vec { + type Target = Vec; + + fn lower(self, tcx: TyCtxt) -> Vec { + self.into_iter().map(|x| x.lower(tcx)).collect() + } +} + +/// A single item as part of an attribute +#[derive(Clone, Debug, RustcEncodable)] +pub struct AttributeItem { + name: LitKind, + kind: AttributeItemKind, + span: SpanData, +} + +impl Lower for ast::MetaItem { + type Target = AttributeItem; + + fn lower(self, tcx: TyCtxt) -> AttributeItem { + AttributeItem { + name: LitKind::Str(self.name, StrStyle::Cooked), + kind: self.node.lower(tcx), + span: SpanData::from_span(self.span, tcx.sess.codemap()), + } + } +} + +impl Lower for ast::NestedMetaItem { + type Target = AttributeItem; + + fn lower(self, tcx: TyCtxt) -> AttributeItem { + match self.node { + ast::NestedMetaItemKind::MetaItem(item) => item.lower(tcx), + ast::NestedMetaItemKind::Literal(lit) => { + AttributeItem { + name: lit.node, + kind: AttributeItemKind::Literal, + span: SpanData::from_span(lit.span, tcx.sess.codemap()), + } + } + } + } +} + +#[derive(Clone, Debug, RustcEncodable)] +pub enum AttributeItemKind { + /// Word meta item. + /// + /// E.g. `test` as in `#[test]` + Literal, + /// Name value meta item. + /// + /// E.g. `feature = "foo"` as in `#[feature = "foo"]` + NameValue(LitKind, SpanData), + /// List meta item. + /// + /// E.g. the `derive(..)` as in `#[derive(..)]` + List(Vec), +} + +impl Lower for ast::MetaItemKind { + type Target = AttributeItemKind; + + fn lower(self, tcx: TyCtxt) -> AttributeItemKind { + match self { + ast::MetaItemKind::Word => AttributeItemKind::Literal, + ast::MetaItemKind::List(items) => { + AttributeItemKind::List(items.into_iter().map(|x| x.lower(tcx)).collect()) + } + ast::MetaItemKind::NameValue(lit) => { + let span = SpanData::from_span(lit.span, tcx.sess.codemap()); + AttributeItemKind::NameValue(lit.node, span) + } + } + } +} + #[derive(Debug, RustcEncodable)] pub struct CratePreludeData { pub crate_name: String, @@ -98,6 +194,7 @@ pub struct EnumData { pub visibility: Visibility, pub docs: String, pub sig: Signature, + pub attributes: Vec, } impl Lower for data::EnumData { @@ -115,6 +212,7 @@ impl Lower for data::EnumData { visibility: self.visibility, docs: self.docs, sig: self.sig.lower(tcx), + attributes: self.attributes.lower(tcx), } } } @@ -179,6 +277,7 @@ pub struct FunctionData { pub parent: Option, pub docs: String, pub sig: Signature, + pub attributes: Vec, } impl Lower for data::FunctionData { @@ -197,6 +296,7 @@ impl Lower for data::FunctionData { parent: self.parent, docs: self.docs, sig: self.sig.lower(tcx), + attributes: self.attributes.lower(tcx), } } } @@ -346,6 +446,7 @@ pub struct MethodData { pub parent: Option, pub docs: String, pub sig: Signature, + pub attributes: Vec, } impl Lower for data::MethodData { @@ -364,6 +465,7 @@ impl Lower for data::MethodData { parent: self.parent, docs: self.docs, sig: self.sig.lower(tcx), + attributes: self.attributes.lower(tcx), } } } @@ -381,6 +483,7 @@ pub struct ModData { pub visibility: Visibility, pub docs: String, pub sig: Signature, + pub attributes: Vec, } impl Lower for data::ModData { @@ -398,6 +501,7 @@ impl Lower for data::ModData { visibility: self.visibility, docs: self.docs, sig: self.sig.lower(tcx), + attributes: self.attributes.lower(tcx), } } } @@ -437,6 +541,7 @@ pub struct StructData { pub visibility: Visibility, pub docs: String, pub sig: Signature, + pub attributes: Vec, } impl Lower for data::StructData { @@ -455,6 +560,7 @@ impl Lower for data::StructData { visibility: self.visibility, docs: self.docs, sig: self.sig.lower(tcx), + attributes: self.attributes.lower(tcx), } } } @@ -471,6 +577,7 @@ pub struct StructVariantData { pub parent: Option, pub docs: String, pub sig: Signature, + pub attributes: Vec, } impl Lower for data::StructVariantData { @@ -488,6 +595,7 @@ impl Lower for data::StructVariantData { parent: self.parent, docs: self.docs, sig: self.sig.lower(tcx), + attributes: self.attributes.lower(tcx), } } } @@ -504,6 +612,7 @@ pub struct TraitData { pub visibility: Visibility, pub docs: String, pub sig: Signature, + pub attributes: Vec, } impl Lower for data::TraitData { @@ -521,6 +630,7 @@ impl Lower for data::TraitData { visibility: self.visibility, docs: self.docs, sig: self.sig.lower(tcx), + attributes: self.attributes.lower(tcx), } } } @@ -537,6 +647,7 @@ pub struct TupleVariantData { pub parent: Option, pub docs: String, pub sig: Signature, + pub attributes: Vec, } impl Lower for data::TupleVariantData { @@ -554,6 +665,7 @@ impl Lower for data::TupleVariantData { parent: self.parent, docs: self.docs, sig: self.sig.lower(tcx), + attributes: self.attributes.lower(tcx), } } } @@ -570,6 +682,7 @@ pub struct TypeDefData { pub parent: Option, pub docs: String, pub sig: Option, + pub attributes: Vec, } impl Lower for data::TypeDefData { @@ -586,6 +699,7 @@ impl Lower for data::TypeDefData { parent: self.parent, docs: self.docs, sig: self.sig.map(|s| s.lower(tcx)), + attributes: self.attributes.lower(tcx), } } } @@ -675,6 +789,7 @@ pub struct VariableData { pub visibility: Visibility, pub docs: String, pub sig: Option, + pub attributes: Vec, } impl Lower for data::VariableData { @@ -694,6 +809,7 @@ impl Lower for data::VariableData { visibility: self.visibility, docs: self.docs, sig: self.sig.map(|s| s.lower(tcx)), + attributes: self.attributes.lower(tcx), } } } diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs index 09752994290c9..1b72489f83c67 100644 --- a/src/librustc_save_analysis/json_dumper.rs +++ b/src/librustc_save_analysis/json_dumper.rs @@ -87,6 +87,7 @@ impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> { decl_id: None, docs: data.docs, sig: Some(From::from(data.sig)), + attributes: data.attributes, }; if def.span.file_name != def.value { // If the module is an out-of-line defintion, then we'll make the @@ -232,6 +233,7 @@ struct Def { decl_id: Option, docs: String, sig: Option, + attributes: Vec, } #[derive(Debug, RustcEncodable)] @@ -274,6 +276,7 @@ impl From for Def { decl_id: None, docs: data.docs, sig: Some(From::from(data.sig)), + attributes: data.attributes, } } } @@ -291,6 +294,7 @@ impl From for Def { decl_id: None, docs: data.docs, sig: Some(From::from(data.sig)), + attributes: data.attributes, } } } @@ -307,6 +311,7 @@ impl From for Def { decl_id: None, docs: data.docs, sig: Some(From::from(data.sig)), + attributes: data.attributes, } } } @@ -323,6 +328,7 @@ impl From for Def { decl_id: None, docs: data.docs, sig: Some(From::from(data.sig)), + attributes: data.attributes, } } } @@ -339,6 +345,7 @@ impl From for Def { decl_id: None, docs: data.docs, sig: Some(From::from(data.sig)), + attributes: data.attributes, } } } @@ -355,6 +362,7 @@ impl From for Def { decl_id: None, docs: data.docs, sig: Some(From::from(data.sig)), + attributes: data.attributes, } } } @@ -371,6 +379,7 @@ impl From for Def { decl_id: data.decl_id.map(|id| From::from(id)), docs: data.docs, sig: Some(From::from(data.sig)), + attributes: data.attributes, } } } @@ -387,6 +396,7 @@ impl From for Def { decl_id: None, docs: data.docs, sig: None, + attributes: vec![], } } } @@ -403,6 +413,7 @@ impl From for Def { decl_id: None, docs: String::new(), sig: data.sig.map(|s| From::from(s)), + attributes: data.attributes, } } } @@ -424,6 +435,7 @@ impl From for Def { decl_id: None, docs: data.docs, sig: None, + attributes: data.attributes, } } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index b1e435dcc751c..b650fe1024b23 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -136,6 +136,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { parent: None, docs: docs_for_attrs(&item.attrs), sig: self.sig_base(item), + attributes: remove_docs_from_attrs(&item.attrs), })) } ast::ItemKind::Static(ref typ, mt, ref expr) => { @@ -164,6 +165,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: Some(self.sig_base(item)), + attributes: remove_docs_from_attrs(&item.attrs), })) } ast::ItemKind::Const(ref typ, ref expr) => { @@ -183,6 +185,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: Some(self.sig_base(item)), + attributes: remove_docs_from_attrs(&item.attrs), })) } ast::ItemKind::Mod(ref m) => { @@ -205,6 +208,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: self.sig_base(item), + attributes: remove_docs_from_attrs(&item.attrs), })) } ast::ItemKind::Enum(ref def, _) => { @@ -228,6 +232,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: self.sig_base(item), + attributes: remove_docs_from_attrs(&item.attrs), })) } ast::ItemKind::Impl(.., ref trait_ref, ref typ, _) => { @@ -315,6 +320,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { visibility: From::from(&field.vis), docs: docs_for_attrs(&field.attrs), sig: Some(sig), + attributes: remove_docs_from_attrs(&field.attrs), }) } else { None @@ -327,7 +333,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { name: ast::Name, 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, vis, docs) = + let (qualname, parent_scope, decl_id, vis, docs, attributes) = match self.tcx.impl_of_method(self.tcx.hir.local_def_id(id)) { Some(impl_id) => match self.tcx.hir.get_if_local(impl_id) { Some(Node::NodeItem(item)) => { @@ -349,7 +355,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { (result, trait_id, decl_id, From::from(&item.vis), - docs_for_attrs(&item.attrs)) + docs_for_attrs(&item.attrs), + remove_docs_from_attrs(&item.attrs)) } _ => { span_bug!(span, @@ -374,7 +381,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { (format!("::{}", self.tcx.item_path_str(def_id)), Some(def_id), None, From::from(&item.vis), - docs_for_attrs(&item.attrs)) + docs_for_attrs(&item.attrs), + remove_docs_from_attrs(&item.attrs)) } r => { span_bug!(span, @@ -423,6 +431,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { parent: parent_scope, docs: docs, sig: sig, + attributes: attributes, }) } @@ -836,6 +845,12 @@ fn docs_for_attrs(attrs: &[Attribute]) -> String { result } +/// Remove all attributes which are docs +fn remove_docs_from_attrs(attrs: &[Attribute]) -> Vec { + let doc = Symbol::intern("doc"); + attrs.iter().cloned().filter(|attr| attr.name() != doc).collect() +} + #[derive(Clone, Copy, Debug, RustcEncodable)] pub enum Format { Csv, From 203d22762ddb215af583108d79a521a8441693c2 Mon Sep 17 00:00:00 2001 From: Jonas Bushart Date: Thu, 23 Feb 2017 23:24:12 +0100 Subject: [PATCH 2/3] Store attributes as strings Remove the AST structure --- src/librustc_save_analysis/external_data.rs | 85 +++------------------ 1 file changed, 11 insertions(+), 74 deletions(-) diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs index 0cfa71a349916..38d1df2abb888 100644 --- a/src/librustc_save_analysis/external_data.rs +++ b/src/librustc_save_analysis/external_data.rs @@ -11,8 +11,9 @@ use rustc::hir::def_id::{CrateNum, DefId, DefIndex}; use rustc::hir::map::Map; use rustc::ty::TyCtxt; -use syntax::ast::{self, LitKind, NodeId, StrStyle}; +use syntax::ast::{self, NodeId}; use syntax::codemap::CodeMap; +use syntax::print::pprust; use syntax_pos::Span; use data::{self, Visibility, SigElement}; @@ -67,16 +68,22 @@ impl SpanData { /// Represent an arbitrary attribute on a code element #[derive(Clone, Debug, RustcEncodable)] pub struct Attribute { - value: AttributeItem, + value: String, span: SpanData, } impl Lower for ast::Attribute { type Target = Attribute; - fn lower(self, tcx: TyCtxt) -> Attribute { + fn lower(mut self, tcx: TyCtxt) -> Attribute { + // strip #[] and #![] from the original attributes + self.style = ast::AttrStyle::Outer; + let value = pprust::attribute_to_string(&self); + // #[] are all ASCII which makes this slice save + let value = value[2..value.len()-1].to_string(); + Attribute { - value: self.value.lower(tcx), + value: value, span: SpanData::from_span(self.span, tcx.sess.codemap()), } } @@ -90,76 +97,6 @@ impl Lower for Vec { } } -/// A single item as part of an attribute -#[derive(Clone, Debug, RustcEncodable)] -pub struct AttributeItem { - name: LitKind, - kind: AttributeItemKind, - span: SpanData, -} - -impl Lower for ast::MetaItem { - type Target = AttributeItem; - - fn lower(self, tcx: TyCtxt) -> AttributeItem { - AttributeItem { - name: LitKind::Str(self.name, StrStyle::Cooked), - kind: self.node.lower(tcx), - span: SpanData::from_span(self.span, tcx.sess.codemap()), - } - } -} - -impl Lower for ast::NestedMetaItem { - type Target = AttributeItem; - - fn lower(self, tcx: TyCtxt) -> AttributeItem { - match self.node { - ast::NestedMetaItemKind::MetaItem(item) => item.lower(tcx), - ast::NestedMetaItemKind::Literal(lit) => { - AttributeItem { - name: lit.node, - kind: AttributeItemKind::Literal, - span: SpanData::from_span(lit.span, tcx.sess.codemap()), - } - } - } - } -} - -#[derive(Clone, Debug, RustcEncodable)] -pub enum AttributeItemKind { - /// Word meta item. - /// - /// E.g. `test` as in `#[test]` - Literal, - /// Name value meta item. - /// - /// E.g. `feature = "foo"` as in `#[feature = "foo"]` - NameValue(LitKind, SpanData), - /// List meta item. - /// - /// E.g. the `derive(..)` as in `#[derive(..)]` - List(Vec), -} - -impl Lower for ast::MetaItemKind { - type Target = AttributeItemKind; - - fn lower(self, tcx: TyCtxt) -> AttributeItemKind { - match self { - ast::MetaItemKind::Word => AttributeItemKind::Literal, - ast::MetaItemKind::List(items) => { - AttributeItemKind::List(items.into_iter().map(|x| x.lower(tcx)).collect()) - } - ast::MetaItemKind::NameValue(lit) => { - let span = SpanData::from_span(lit.span, tcx.sess.codemap()); - AttributeItemKind::NameValue(lit.node, span) - } - } - } -} - #[derive(Debug, RustcEncodable)] pub struct CratePreludeData { pub crate_name: String, From db35604792fb64efa0a3deaebc0ea0842e19c67a Mon Sep 17 00:00:00 2001 From: Jonas Bushart Date: Thu, 2 Mar 2017 22:38:57 +0100 Subject: [PATCH 3/3] Move remove_docs_from_attrs into lowering step --- src/librustc_save_analysis/dump_visitor.rs | 17 +++++---- src/librustc_save_analysis/external_data.rs | 38 +++++++++++---------- src/librustc_save_analysis/lib.rs | 22 +++++------- 3 files changed, 36 insertions(+), 41 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 54069775418ce..cbb1a3e502363 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -47,8 +47,7 @@ use syntax::ptr::P; use syntax::codemap::Spanned; use syntax_pos::*; -use super::{escape, generated_code, SaveContext, PathCollector, docs_for_attrs, - remove_docs_from_attrs}; +use super::{escape, generated_code, SaveContext, PathCollector, docs_for_attrs}; use super::data::*; use super::dump::Dump; use super::external_data::{Lower, make_def_id}; @@ -450,7 +449,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { visibility: vis, docs: docs_for_attrs(attrs), sig: method_data.sig, - attributes: remove_docs_from_attrs(attrs), + attributes: attrs.to_vec(), }.lower(self.tcx)); } @@ -596,7 +595,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { visibility: vis, docs: docs_for_attrs(attrs), sig: None, - attributes: remove_docs_from_attrs(attrs), + attributes: attrs.to_vec(), }.lower(self.tcx)); } @@ -641,7 +640,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: self.save_ctxt.sig_base(item), - attributes: remove_docs_from_attrs(&item.attrs), + attributes: item.attrs.clone(), }.lower(self.tcx)); } @@ -707,7 +706,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { parent: Some(make_def_id(item.id, &self.tcx.hir)), docs: docs_for_attrs(&variant.node.attrs), sig: sig, - attributes: remove_docs_from_attrs(&variant.node.attrs), + attributes: variant.node.attrs.clone(), }.lower(self.tcx)); } } @@ -734,7 +733,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { parent: Some(make_def_id(item.id, &self.tcx.hir)), docs: docs_for_attrs(&variant.node.attrs), sig: sig, - attributes: remove_docs_from_attrs(&variant.node.attrs), + attributes: variant.node.attrs.clone(), }.lower(self.tcx)); } } @@ -806,7 +805,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: self.save_ctxt.sig_base(item), - attributes: remove_docs_from_attrs(&item.attrs), + attributes: item.attrs.clone(), }.lower(self.tcx)); } @@ -1315,7 +1314,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll, parent: None, docs: docs_for_attrs(&item.attrs), sig: Some(self.save_ctxt.sig_base(item)), - attributes: remove_docs_from_attrs(&item.attrs), + attributes: item.attrs.clone(), }.lower(self.tcx)); } diff --git a/src/librustc_save_analysis/external_data.rs b/src/librustc_save_analysis/external_data.rs index 38d1df2abb888..41658dc5b1b48 100644 --- a/src/librustc_save_analysis/external_data.rs +++ b/src/librustc_save_analysis/external_data.rs @@ -14,6 +14,7 @@ use rustc::ty::TyCtxt; use syntax::ast::{self, NodeId}; use syntax::codemap::CodeMap; use syntax::print::pprust; +use syntax::symbol::Symbol; use syntax_pos::Span; use data::{self, Visibility, SigElement}; @@ -72,28 +73,29 @@ pub struct Attribute { span: SpanData, } -impl Lower for ast::Attribute { - type Target = Attribute; - - fn lower(mut self, tcx: TyCtxt) -> Attribute { - // strip #[] and #![] from the original attributes - self.style = ast::AttrStyle::Outer; - let value = pprust::attribute_to_string(&self); - // #[] are all ASCII which makes this slice save - let value = value[2..value.len()-1].to_string(); - - Attribute { - value: value, - span: SpanData::from_span(self.span, tcx.sess.codemap()), - } - } -} - impl Lower for Vec { type Target = Vec; fn lower(self, tcx: TyCtxt) -> Vec { - self.into_iter().map(|x| x.lower(tcx)).collect() + let doc = Symbol::intern("doc"); + self.into_iter() + // Only retain real attributes. Doc comments are lowered separately. + .filter(|attr| attr.name() != doc) + .map(|mut attr| { + // Remove the surrounding '#[..]' or '#![..]' of the pretty printed + // attribute. First normalize all inner attribute (#![..]) to outer + // ones (#[..]), then remove the two leading and the one trailing character. + attr.style = ast::AttrStyle::Outer; + let value = pprust::attribute_to_string(&attr); + // This str slicing works correctly, because the leading and trailing characters + // are in the ASCII range and thus exactly one byte each. + let value = value[2..value.len()-1].to_string(); + + Attribute { + value: value, + span: SpanData::from_span(attr.span, tcx.sess.codemap()), + } + }).collect() } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index b650fe1024b23..2153b30b62cd5 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -136,7 +136,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { parent: None, docs: docs_for_attrs(&item.attrs), sig: self.sig_base(item), - attributes: remove_docs_from_attrs(&item.attrs), + attributes: item.attrs.clone(), })) } ast::ItemKind::Static(ref typ, mt, ref expr) => { @@ -165,7 +165,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: Some(self.sig_base(item)), - attributes: remove_docs_from_attrs(&item.attrs), + attributes: item.attrs.clone(), })) } ast::ItemKind::Const(ref typ, ref expr) => { @@ -185,7 +185,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: Some(self.sig_base(item)), - attributes: remove_docs_from_attrs(&item.attrs), + attributes: item.attrs.clone(), })) } ast::ItemKind::Mod(ref m) => { @@ -208,7 +208,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: self.sig_base(item), - attributes: remove_docs_from_attrs(&item.attrs), + attributes: item.attrs.clone(), })) } ast::ItemKind::Enum(ref def, _) => { @@ -232,7 +232,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { visibility: From::from(&item.vis), docs: docs_for_attrs(&item.attrs), sig: self.sig_base(item), - attributes: remove_docs_from_attrs(&item.attrs), + attributes: item.attrs.clone(), })) } ast::ItemKind::Impl(.., ref trait_ref, ref typ, _) => { @@ -320,7 +320,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { visibility: From::from(&field.vis), docs: docs_for_attrs(&field.attrs), sig: Some(sig), - attributes: remove_docs_from_attrs(&field.attrs), + attributes: field.attrs.clone(), }) } else { None @@ -356,7 +356,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { (result, trait_id, decl_id, From::from(&item.vis), docs_for_attrs(&item.attrs), - remove_docs_from_attrs(&item.attrs)) + item.attrs.to_vec()) } _ => { span_bug!(span, @@ -382,7 +382,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { Some(def_id), None, From::from(&item.vis), docs_for_attrs(&item.attrs), - remove_docs_from_attrs(&item.attrs)) + item.attrs.to_vec()) } r => { span_bug!(span, @@ -845,12 +845,6 @@ fn docs_for_attrs(attrs: &[Attribute]) -> String { result } -/// Remove all attributes which are docs -fn remove_docs_from_attrs(attrs: &[Attribute]) -> Vec { - let doc = Symbol::intern("doc"); - attrs.iter().cloned().filter(|attr| attr.name() != doc).collect() -} - #[derive(Clone, Copy, Debug, RustcEncodable)] pub enum Format { Csv,