Skip to content

Commit 0f1847c

Browse files
authored
Rollup merge of rust-lang#39820 - jonasbb:export-attributes, r=nrc
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 } } ] ```
2 parents c6153b2 + 5bfa0f3 commit 0f1847c

File tree

5 files changed

+102
-5
lines changed

5 files changed

+102
-5
lines changed

src/librustc_save_analysis/data.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
1616
use rustc::hir;
1717
use rustc::hir::def_id::{CrateNum, DefId};
18-
use syntax::ast::{self, NodeId};
18+
use syntax::ast::{self, Attribute, NodeId};
1919
use syntax_pos::Span;
2020

2121
pub struct CrateData {
@@ -136,6 +136,7 @@ pub struct EnumData {
136136
pub visibility: Visibility,
137137
pub docs: String,
138138
pub sig: Signature,
139+
pub attributes: Vec<Attribute>,
139140
}
140141

141142
/// Data for extern crates.
@@ -171,6 +172,7 @@ pub struct FunctionData {
171172
pub parent: Option<DefId>,
172173
pub docs: String,
173174
pub sig: Signature,
175+
pub attributes: Vec<Attribute>,
174176
}
175177

176178
/// Data about a function call.
@@ -256,6 +258,7 @@ pub struct MethodData {
256258
pub visibility: Visibility,
257259
pub docs: String,
258260
pub sig: Signature,
261+
pub attributes: Vec<Attribute>,
259262
}
260263

261264
/// Data for modules.
@@ -271,6 +274,7 @@ pub struct ModData {
271274
pub visibility: Visibility,
272275
pub docs: String,
273276
pub sig: Signature,
277+
pub attributes: Vec<Attribute>,
274278
}
275279

276280
/// Data for a reference to a module.
@@ -295,6 +299,7 @@ pub struct StructData {
295299
pub visibility: Visibility,
296300
pub docs: String,
297301
pub sig: Signature,
302+
pub attributes: Vec<Attribute>,
298303
}
299304

300305
#[derive(Debug, RustcEncodable)]
@@ -309,6 +314,7 @@ pub struct StructVariantData {
309314
pub parent: Option<DefId>,
310315
pub docs: String,
311316
pub sig: Signature,
317+
pub attributes: Vec<Attribute>,
312318
}
313319

314320
#[derive(Debug, RustcEncodable)]
@@ -323,6 +329,7 @@ pub struct TraitData {
323329
pub visibility: Visibility,
324330
pub docs: String,
325331
pub sig: Signature,
332+
pub attributes: Vec<Attribute>,
326333
}
327334

328335
#[derive(Debug, RustcEncodable)]
@@ -337,6 +344,7 @@ pub struct TupleVariantData {
337344
pub parent: Option<DefId>,
338345
pub docs: String,
339346
pub sig: Signature,
347+
pub attributes: Vec<Attribute>,
340348
}
341349

342350
/// Data for a typedef.
@@ -351,6 +359,7 @@ pub struct TypeDefData {
351359
pub parent: Option<DefId>,
352360
pub docs: String,
353361
pub sig: Option<Signature>,
362+
pub attributes: Vec<Attribute>,
354363
}
355364

356365
/// Data for a reference to a type or trait.
@@ -396,6 +405,7 @@ pub struct VariableData {
396405
pub visibility: Visibility,
397406
pub docs: String,
398407
pub sig: Option<Signature>,
408+
pub attributes: Vec<Attribute>,
399409
}
400410

401411
#[derive(Debug, RustcEncodable)]

src/librustc_save_analysis/dump_visitor.rs

+11
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
373373
visibility: Visibility::Inherited,
374374
docs: String::new(),
375375
sig: None,
376+
attributes: vec![],
376377
}.lower(self.tcx));
377378
}
378379
}
@@ -448,6 +449,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
448449
visibility: vis,
449450
docs: docs_for_attrs(attrs),
450451
sig: method_data.sig,
452+
attributes: attrs.to_vec(),
451453
}.lower(self.tcx));
452454
}
453455

@@ -519,6 +521,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
519521
parent: None,
520522
docs: String::new(),
521523
sig: None,
524+
attributes: vec![],
522525
}.lower(self.tcx));
523526
}
524527
}
@@ -592,6 +595,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
592595
visibility: vis,
593596
docs: docs_for_attrs(attrs),
594597
sig: None,
598+
attributes: attrs.to_vec(),
595599
}.lower(self.tcx));
596600
}
597601

@@ -636,6 +640,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
636640
visibility: From::from(&item.vis),
637641
docs: docs_for_attrs(&item.attrs),
638642
sig: self.save_ctxt.sig_base(item),
643+
attributes: item.attrs.clone(),
639644
}.lower(self.tcx));
640645
}
641646

@@ -701,6 +706,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
701706
parent: Some(make_def_id(item.id, &self.tcx.hir)),
702707
docs: docs_for_attrs(&variant.node.attrs),
703708
sig: sig,
709+
attributes: variant.node.attrs.clone(),
704710
}.lower(self.tcx));
705711
}
706712
}
@@ -727,6 +733,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
727733
parent: Some(make_def_id(item.id, &self.tcx.hir)),
728734
docs: docs_for_attrs(&variant.node.attrs),
729735
sig: sig,
736+
attributes: variant.node.attrs.clone(),
730737
}.lower(self.tcx));
731738
}
732739
}
@@ -798,6 +805,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
798805
visibility: From::from(&item.vis),
799806
docs: docs_for_attrs(&item.attrs),
800807
sig: self.save_ctxt.sig_base(item),
808+
attributes: item.attrs.clone(),
801809
}.lower(self.tcx));
802810
}
803811

@@ -1064,6 +1072,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
10641072
visibility: Visibility::Inherited,
10651073
docs: String::new(),
10661074
sig: None,
1075+
attributes: vec![],
10671076
}.lower(self.tcx));
10681077
}
10691078
}
@@ -1305,6 +1314,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll,
13051314
parent: None,
13061315
docs: docs_for_attrs(&item.attrs),
13071316
sig: Some(self.save_ctxt.sig_base(item)),
1317+
attributes: item.attrs.clone(),
13081318
}.lower(self.tcx));
13091319
}
13101320

@@ -1527,6 +1537,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'l> for DumpVisitor<'l, 'tcx, 'll,
15271537
visibility: Visibility::Inherited,
15281538
docs: String::new(),
15291539
sig: None,
1540+
attributes: vec![],
15301541
}.lower(self.tcx));
15311542
}
15321543
}

src/librustc_save_analysis/external_data.rs

+56-1
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
use rustc::hir::def_id::{CrateNum, DefId, DefIndex};
1212
use rustc::hir::map::Map;
1313
use rustc::ty::TyCtxt;
14-
use syntax::ast::NodeId;
14+
use syntax::ast::{self, NodeId};
1515
use syntax::codemap::CodeMap;
16+
use syntax::print::pprust;
17+
use syntax::symbol::Symbol;
1618
use syntax_pos::Span;
1719

1820
use data::{self, Visibility, SigElement};
@@ -64,6 +66,39 @@ impl SpanData {
6466
}
6567
}
6668

69+
/// Represent an arbitrary attribute on a code element
70+
#[derive(Clone, Debug, RustcEncodable)]
71+
pub struct Attribute {
72+
value: String,
73+
span: SpanData,
74+
}
75+
76+
impl Lower for Vec<ast::Attribute> {
77+
type Target = Vec<Attribute>;
78+
79+
fn lower(self, tcx: TyCtxt) -> Vec<Attribute> {
80+
let doc = Symbol::intern("doc");
81+
self.into_iter()
82+
// Only retain real attributes. Doc comments are lowered separately.
83+
.filter(|attr| attr.name() != doc)
84+
.map(|mut attr| {
85+
// Remove the surrounding '#[..]' or '#![..]' of the pretty printed
86+
// attribute. First normalize all inner attribute (#![..]) to outer
87+
// ones (#[..]), then remove the two leading and the one trailing character.
88+
attr.style = ast::AttrStyle::Outer;
89+
let value = pprust::attribute_to_string(&attr);
90+
// This str slicing works correctly, because the leading and trailing characters
91+
// are in the ASCII range and thus exactly one byte each.
92+
let value = value[2..value.len()-1].to_string();
93+
94+
Attribute {
95+
value: value,
96+
span: SpanData::from_span(attr.span, tcx.sess.codemap()),
97+
}
98+
}).collect()
99+
}
100+
}
101+
67102
#[derive(Debug, RustcEncodable)]
68103
pub struct CratePreludeData {
69104
pub crate_name: String,
@@ -98,6 +133,7 @@ pub struct EnumData {
98133
pub visibility: Visibility,
99134
pub docs: String,
100135
pub sig: Signature,
136+
pub attributes: Vec<Attribute>,
101137
}
102138

103139
impl Lower for data::EnumData {
@@ -115,6 +151,7 @@ impl Lower for data::EnumData {
115151
visibility: self.visibility,
116152
docs: self.docs,
117153
sig: self.sig.lower(tcx),
154+
attributes: self.attributes.lower(tcx),
118155
}
119156
}
120157
}
@@ -179,6 +216,7 @@ pub struct FunctionData {
179216
pub parent: Option<DefId>,
180217
pub docs: String,
181218
pub sig: Signature,
219+
pub attributes: Vec<Attribute>,
182220
}
183221

184222
impl Lower for data::FunctionData {
@@ -197,6 +235,7 @@ impl Lower for data::FunctionData {
197235
parent: self.parent,
198236
docs: self.docs,
199237
sig: self.sig.lower(tcx),
238+
attributes: self.attributes.lower(tcx),
200239
}
201240
}
202241
}
@@ -346,6 +385,7 @@ pub struct MethodData {
346385
pub parent: Option<DefId>,
347386
pub docs: String,
348387
pub sig: Signature,
388+
pub attributes: Vec<Attribute>,
349389
}
350390

351391
impl Lower for data::MethodData {
@@ -364,6 +404,7 @@ impl Lower for data::MethodData {
364404
parent: self.parent,
365405
docs: self.docs,
366406
sig: self.sig.lower(tcx),
407+
attributes: self.attributes.lower(tcx),
367408
}
368409
}
369410
}
@@ -381,6 +422,7 @@ pub struct ModData {
381422
pub visibility: Visibility,
382423
pub docs: String,
383424
pub sig: Signature,
425+
pub attributes: Vec<Attribute>,
384426
}
385427

386428
impl Lower for data::ModData {
@@ -398,6 +440,7 @@ impl Lower for data::ModData {
398440
visibility: self.visibility,
399441
docs: self.docs,
400442
sig: self.sig.lower(tcx),
443+
attributes: self.attributes.lower(tcx),
401444
}
402445
}
403446
}
@@ -437,6 +480,7 @@ pub struct StructData {
437480
pub visibility: Visibility,
438481
pub docs: String,
439482
pub sig: Signature,
483+
pub attributes: Vec<Attribute>,
440484
}
441485

442486
impl Lower for data::StructData {
@@ -455,6 +499,7 @@ impl Lower for data::StructData {
455499
visibility: self.visibility,
456500
docs: self.docs,
457501
sig: self.sig.lower(tcx),
502+
attributes: self.attributes.lower(tcx),
458503
}
459504
}
460505
}
@@ -471,6 +516,7 @@ pub struct StructVariantData {
471516
pub parent: Option<DefId>,
472517
pub docs: String,
473518
pub sig: Signature,
519+
pub attributes: Vec<Attribute>,
474520
}
475521

476522
impl Lower for data::StructVariantData {
@@ -488,6 +534,7 @@ impl Lower for data::StructVariantData {
488534
parent: self.parent,
489535
docs: self.docs,
490536
sig: self.sig.lower(tcx),
537+
attributes: self.attributes.lower(tcx),
491538
}
492539
}
493540
}
@@ -504,6 +551,7 @@ pub struct TraitData {
504551
pub visibility: Visibility,
505552
pub docs: String,
506553
pub sig: Signature,
554+
pub attributes: Vec<Attribute>,
507555
}
508556

509557
impl Lower for data::TraitData {
@@ -521,6 +569,7 @@ impl Lower for data::TraitData {
521569
visibility: self.visibility,
522570
docs: self.docs,
523571
sig: self.sig.lower(tcx),
572+
attributes: self.attributes.lower(tcx),
524573
}
525574
}
526575
}
@@ -537,6 +586,7 @@ pub struct TupleVariantData {
537586
pub parent: Option<DefId>,
538587
pub docs: String,
539588
pub sig: Signature,
589+
pub attributes: Vec<Attribute>,
540590
}
541591

542592
impl Lower for data::TupleVariantData {
@@ -554,6 +604,7 @@ impl Lower for data::TupleVariantData {
554604
parent: self.parent,
555605
docs: self.docs,
556606
sig: self.sig.lower(tcx),
607+
attributes: self.attributes.lower(tcx),
557608
}
558609
}
559610
}
@@ -570,6 +621,7 @@ pub struct TypeDefData {
570621
pub parent: Option<DefId>,
571622
pub docs: String,
572623
pub sig: Option<Signature>,
624+
pub attributes: Vec<Attribute>,
573625
}
574626

575627
impl Lower for data::TypeDefData {
@@ -586,6 +638,7 @@ impl Lower for data::TypeDefData {
586638
parent: self.parent,
587639
docs: self.docs,
588640
sig: self.sig.map(|s| s.lower(tcx)),
641+
attributes: self.attributes.lower(tcx),
589642
}
590643
}
591644
}
@@ -675,6 +728,7 @@ pub struct VariableData {
675728
pub visibility: Visibility,
676729
pub docs: String,
677730
pub sig: Option<Signature>,
731+
pub attributes: Vec<Attribute>,
678732
}
679733

680734
impl Lower for data::VariableData {
@@ -694,6 +748,7 @@ impl Lower for data::VariableData {
694748
visibility: self.visibility,
695749
docs: self.docs,
696750
sig: self.sig.map(|s| s.lower(tcx)),
751+
attributes: self.attributes.lower(tcx),
697752
}
698753
}
699754
}

0 commit comments

Comments
 (0)