Skip to content

Commit

Permalink
Rollup merge of rust-lang#39820 - jonasbb:export-attributes, r=nrc
Browse files Browse the repository at this point in the history
Export attributes in save-analysis data

Since this is my first pull-request to rust, I would like to get some feedback about obvious errors in this implementation.

I would like to change the save-analysis data to include arbitrary attribute data.
A use-case I have in mind for this is identifying functions with `#[test]` annotations such that tools like rls can offer a test-runner feature. I described my idea here [rls#173](rust-lang/rls#173).

My changes contain:

1. track a vector of attributes in the various `*Data` types in `data.rs` and `external_data.rs`
2. implement lowering for `Attribute` and `MetaItem`
3. adjust `JsonDumper` to print the attributes

In the lowering of `Attribute` I remove the distinction between `MetaItem` and `NestedMetaItem`. I did this because this distinction is somewhat confusing. For example, `NestedMetaItemKind::Literal` has two identical spans, because both `NestedMetaItem` and `Lit` are defined as `Spanned<_>`.
My model is strictly more general, as it allows an `LitKind` instead of a `Symbol` for `MetaItem` and `Symbol`s are converted into a cooked string. As a consumer of the save-analysis data this shouldn't affect you much.

Example json output of `#[test]` annotation:
```
"attributes": [
  {
    "value": {
      "name": {
        "variant": "Str",
        "fields": [
          "test",
          "Cooked"
        ]
      },
      "kind": "Literal",
      "span": {
        "file_name": "test.rs",
        "byte_start": 2,
        "byte_end": 6,
        "line_start": 1,
        "line_end": 1,
        "column_start": 3,
        "column_end": 7
      }
    },
    "span": {
      "file_name": "test.rs",
      "byte_start": 0,
      "byte_end": 7,
      "line_start": 1,
      "line_end": 1,
      "column_start": 1,
      "column_end": 8
    }
  }
]
```
  • Loading branch information
alexcrichton authored Mar 10, 2017
2 parents 5bb0dc2 + 5bfa0f3 commit 34f0d7b
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 5 deletions.
12 changes: 11 additions & 1 deletion src/librustc_save_analysis/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -136,6 +136,7 @@ pub struct EnumData {
pub visibility: Visibility,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

/// Data for extern crates.
Expand Down Expand Up @@ -171,6 +172,7 @@ pub struct FunctionData {
pub parent: Option<DefId>,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

/// Data about a function call.
Expand Down Expand Up @@ -256,6 +258,7 @@ pub struct MethodData {
pub visibility: Visibility,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

/// Data for modules.
Expand All @@ -271,6 +274,7 @@ pub struct ModData {
pub visibility: Visibility,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

/// Data for a reference to a module.
Expand All @@ -295,6 +299,7 @@ pub struct StructData {
pub visibility: Visibility,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

#[derive(Debug, RustcEncodable)]
Expand All @@ -309,6 +314,7 @@ pub struct StructVariantData {
pub parent: Option<DefId>,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

#[derive(Debug, RustcEncodable)]
Expand All @@ -323,6 +329,7 @@ pub struct TraitData {
pub visibility: Visibility,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

#[derive(Debug, RustcEncodable)]
Expand All @@ -337,6 +344,7 @@ pub struct TupleVariantData {
pub parent: Option<DefId>,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

/// Data for a typedef.
Expand All @@ -351,6 +359,7 @@ pub struct TypeDefData {
pub parent: Option<DefId>,
pub docs: String,
pub sig: Option<Signature>,
pub attributes: Vec<Attribute>,
}

/// Data for a reference to a type or trait.
Expand Down Expand Up @@ -396,6 +405,7 @@ pub struct VariableData {
pub visibility: Visibility,
pub docs: String,
pub sig: Option<Signature>,
pub attributes: Vec<Attribute>,
}

#[derive(Debug, RustcEncodable)]
Expand Down
11 changes: 11 additions & 0 deletions src/librustc_save_analysis/dump_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,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));
}
}
Expand Down Expand Up @@ -448,6 +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: attrs.to_vec(),
}.lower(self.tcx));
}

Expand Down Expand Up @@ -519,6 +521,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));
}
}
Expand Down Expand Up @@ -592,6 +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: attrs.to_vec(),
}.lower(self.tcx));
}

Expand Down Expand Up @@ -636,6 +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: item.attrs.clone(),
}.lower(self.tcx));
}

Expand Down Expand Up @@ -701,6 +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: variant.node.attrs.clone(),
}.lower(self.tcx));
}
}
Expand All @@ -727,6 +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: variant.node.attrs.clone(),
}.lower(self.tcx));
}
}
Expand Down Expand Up @@ -798,6 +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: item.attrs.clone(),
}.lower(self.tcx));
}

Expand Down Expand Up @@ -1064,6 +1072,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));
}
}
Expand Down Expand Up @@ -1305,6 +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: item.attrs.clone(),
}.lower(self.tcx));
}

Expand Down Expand Up @@ -1527,6 +1537,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));
}
}
Expand Down
57 changes: 56 additions & 1 deletion src/librustc_save_analysis/external_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@
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, NodeId};
use syntax::codemap::CodeMap;
use syntax::print::pprust;
use syntax::symbol::Symbol;
use syntax_pos::Span;

use data::{self, Visibility, SigElement};
Expand Down Expand Up @@ -64,6 +66,39 @@ impl SpanData {
}
}

/// Represent an arbitrary attribute on a code element
#[derive(Clone, Debug, RustcEncodable)]
pub struct Attribute {
value: String,
span: SpanData,
}

impl Lower for Vec<ast::Attribute> {
type Target = Vec<Attribute>;

fn lower(self, tcx: TyCtxt) -> Vec<Attribute> {
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()
}
}

#[derive(Debug, RustcEncodable)]
pub struct CratePreludeData {
pub crate_name: String,
Expand Down Expand Up @@ -98,6 +133,7 @@ pub struct EnumData {
pub visibility: Visibility,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

impl Lower for data::EnumData {
Expand All @@ -115,6 +151,7 @@ impl Lower for data::EnumData {
visibility: self.visibility,
docs: self.docs,
sig: self.sig.lower(tcx),
attributes: self.attributes.lower(tcx),
}
}
}
Expand Down Expand Up @@ -179,6 +216,7 @@ pub struct FunctionData {
pub parent: Option<DefId>,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

impl Lower for data::FunctionData {
Expand All @@ -197,6 +235,7 @@ impl Lower for data::FunctionData {
parent: self.parent,
docs: self.docs,
sig: self.sig.lower(tcx),
attributes: self.attributes.lower(tcx),
}
}
}
Expand Down Expand Up @@ -346,6 +385,7 @@ pub struct MethodData {
pub parent: Option<DefId>,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

impl Lower for data::MethodData {
Expand All @@ -364,6 +404,7 @@ impl Lower for data::MethodData {
parent: self.parent,
docs: self.docs,
sig: self.sig.lower(tcx),
attributes: self.attributes.lower(tcx),
}
}
}
Expand All @@ -381,6 +422,7 @@ pub struct ModData {
pub visibility: Visibility,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

impl Lower for data::ModData {
Expand All @@ -398,6 +440,7 @@ impl Lower for data::ModData {
visibility: self.visibility,
docs: self.docs,
sig: self.sig.lower(tcx),
attributes: self.attributes.lower(tcx),
}
}
}
Expand Down Expand Up @@ -437,6 +480,7 @@ pub struct StructData {
pub visibility: Visibility,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

impl Lower for data::StructData {
Expand All @@ -455,6 +499,7 @@ impl Lower for data::StructData {
visibility: self.visibility,
docs: self.docs,
sig: self.sig.lower(tcx),
attributes: self.attributes.lower(tcx),
}
}
}
Expand All @@ -471,6 +516,7 @@ pub struct StructVariantData {
pub parent: Option<DefId>,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

impl Lower for data::StructVariantData {
Expand All @@ -488,6 +534,7 @@ impl Lower for data::StructVariantData {
parent: self.parent,
docs: self.docs,
sig: self.sig.lower(tcx),
attributes: self.attributes.lower(tcx),
}
}
}
Expand All @@ -504,6 +551,7 @@ pub struct TraitData {
pub visibility: Visibility,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

impl Lower for data::TraitData {
Expand All @@ -521,6 +569,7 @@ impl Lower for data::TraitData {
visibility: self.visibility,
docs: self.docs,
sig: self.sig.lower(tcx),
attributes: self.attributes.lower(tcx),
}
}
}
Expand All @@ -537,6 +586,7 @@ pub struct TupleVariantData {
pub parent: Option<DefId>,
pub docs: String,
pub sig: Signature,
pub attributes: Vec<Attribute>,
}

impl Lower for data::TupleVariantData {
Expand All @@ -554,6 +604,7 @@ impl Lower for data::TupleVariantData {
parent: self.parent,
docs: self.docs,
sig: self.sig.lower(tcx),
attributes: self.attributes.lower(tcx),
}
}
}
Expand All @@ -570,6 +621,7 @@ pub struct TypeDefData {
pub parent: Option<DefId>,
pub docs: String,
pub sig: Option<Signature>,
pub attributes: Vec<Attribute>,
}

impl Lower for data::TypeDefData {
Expand All @@ -586,6 +638,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),
}
}
}
Expand Down Expand Up @@ -675,6 +728,7 @@ pub struct VariableData {
pub visibility: Visibility,
pub docs: String,
pub sig: Option<Signature>,
pub attributes: Vec<Attribute>,
}

impl Lower for data::VariableData {
Expand All @@ -694,6 +748,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),
}
}
}
Expand Down
Loading

0 comments on commit 34f0d7b

Please sign in to comment.