Skip to content

Commit dca29d7

Browse files
committedMay 3, 2016
save-analysis: use a decoupled representation for dumped data
Closes #33348
1 parent 7d8100a commit dca29d7

File tree

8 files changed

+752
-838
lines changed

8 files changed

+752
-838
lines changed
 

‎src/librustc_save_analysis/csv_dumper.rs

+35-84
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,20 @@
1010

1111
use std::io::Write;
1212

13-
use rustc::hir::def_id::{DefId, DefIndex};
14-
use syntax::codemap::Span;
15-
16-
use super::data::*;
13+
use super::external_data::*;
1714
use super::dump::Dump;
18-
use super::span_utils::SpanUtils;
1915

20-
pub struct CsvDumper<'tcx, 'b, W: 'b> {
21-
output: &'b mut W,
22-
span: SpanUtils<'tcx>
16+
pub struct CsvDumper<'b, W: 'b> {
17+
output: &'b mut W
2318
}
2419

25-
impl<'a, 'b, W: Write> CsvDumper<'a, 'b, W> {
26-
pub fn new(writer: &'b mut W, span: SpanUtils<'a>) -> CsvDumper<'a, 'b, W> {
27-
CsvDumper { output: writer, span: span }
20+
impl<'b, W: Write> CsvDumper<'b, W> {
21+
pub fn new(writer: &'b mut W) -> CsvDumper<'b, W> {
22+
CsvDumper { output: writer }
2823
}
2924

30-
fn record(&mut self, kind: &str, span: Span, values: String) {
31-
let span_str = self.span.extent_str(span);
25+
fn record(&mut self, kind: &str, span: SpanData, values: String) {
26+
let span_str = span_extent_str(span);
3227
if let Err(_) = write!(self.output, "{},{}{}\n", kind, span_str, values) {
3328
error!("Error writing output");
3429
}
@@ -41,7 +36,7 @@ impl<'a, 'b, W: Write> CsvDumper<'a, 'b, W> {
4136
}
4237
}
4338

44-
impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
39+
impl<'b, W: Write + 'b> Dump for CsvDumper<'b, W> {
4540
fn crate_prelude(&mut self, data: CratePreludeData) {
4641
let values = make_values_str(&[
4742
("name", &data.crate_name),
@@ -93,68 +88,50 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
9388
}
9489

9590
fn impl_data(&mut self, data: ImplData) {
96-
let self_ref = data.self_ref.unwrap_or(null_def_id());
97-
let trait_ref = data.trait_ref.unwrap_or(null_def_id());
98-
9991
let id = data.id.to_string();
100-
let ref_id = self_ref.index.as_usize().to_string();
101-
let ref_id_crate = self_ref.krate.to_string();
102-
let trait_id = trait_ref.index.as_usize().to_string();
103-
let trait_id_crate = trait_ref.krate.to_string();
92+
let ref_id = data.self_ref.unwrap_or(Id::null()).to_string();
93+
let trait_id = data.trait_ref.unwrap_or(Id::null()).to_string();
10494
let scope = data.scope.to_string();
10595
let values = make_values_str(&[
10696
("id", &id),
10797
("refid", &ref_id),
108-
("refidcrate", &ref_id_crate),
10998
("traitid", &trait_id),
110-
("traitidcrate", &trait_id_crate),
11199
("scopeid", &scope)
112100
]);
113101

114102
self.record("impl", data.span, values);
115103
}
116104

117105
fn inheritance(&mut self, data: InheritanceData) {
118-
let base_id = data.base_id.index.as_usize().to_string();
119-
let base_crate = data.base_id.krate.to_string();
120-
let deriv_id = data.deriv_id.to_string();
121-
let deriv_crate = 0.to_string();
122-
let values = make_values_str(&[
123-
("base", &base_id),
124-
("basecrate", &base_crate),
125-
("derived", &deriv_id),
126-
("derivedcrate", &deriv_crate)
127-
]);
106+
let base_id = data.base_id.to_string();
107+
let deriv_id = data.deriv_id.to_string();
108+
let values = make_values_str(&[
109+
("base", &base_id),
110+
("derived", &deriv_id),
111+
]);
128112

129113
self.record("inheritance", data.span, values);
130114
}
131115

132116
fn function(&mut self, data: FunctionData) {
133-
let (decl_id, decl_crate) = match data.declaration {
134-
Some(id) => (id.index.as_usize().to_string(), id.krate.to_string()),
135-
None => (String::new(), String::new())
136-
};
137-
138117
let id = data.id.to_string();
118+
let decl_id = data.declaration.unwrap_or(Id::null()).to_string();
139119
let scope = data.scope.to_string();
140120
let values = make_values_str(&[
141121
("id", &id),
142122
("qualname", &data.qualname),
143123
("declid", &decl_id),
144-
("declidcrate", &decl_crate),
145124
("scopeid", &scope)
146125
]);
147126

148127
self.record("function", data.span, values);
149128
}
150129

151130
fn function_ref(&mut self, data: FunctionRefData) {
152-
let ref_id = data.ref_id.index.as_usize().to_string();
153-
let ref_crate = data.ref_id.krate.to_string();
131+
let ref_id = data.ref_id.to_string();
154132
let scope = data.scope.to_string();
155133
let values = make_values_str(&[
156134
("refid", &ref_id),
157-
("refidcrate", &ref_crate),
158135
("qualname", ""),
159136
("scopeid", &scope)
160137
]);
@@ -163,13 +140,11 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
163140
}
164141

165142
fn function_call(&mut self, data: FunctionCallData) {
166-
let ref_id = data.ref_id.index.as_usize().to_string();
167-
let ref_crate = data.ref_id.krate.to_string();
143+
let ref_id = data.ref_id.to_string();
168144
let qualname = String::new();
169145
let scope = data.scope.to_string();
170146
let values = make_values_str(&[
171147
("refid", &ref_id),
172-
("refidcrate", &ref_crate),
173148
("qualname", &qualname),
174149
("scopeid", &scope)
175150
]);
@@ -190,21 +165,12 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
190165
}
191166

192167
fn method_call(&mut self, data: MethodCallData) {
193-
let (dcn, dck) = match data.decl_id {
194-
Some(declid) => (declid.index.as_usize().to_string(), declid.krate.to_string()),
195-
None => (String::new(), String::new()),
196-
};
197-
198-
let ref_id = data.ref_id.unwrap_or(null_def_id());
199-
200-
let def_id = ref_id.index.as_usize().to_string();
201-
let def_crate = ref_id.krate.to_string();
168+
let decl_id = data.decl_id.unwrap_or(Id::null()).to_string();
169+
let ref_id = data.ref_id.unwrap_or(Id::null()).to_string();
202170
let scope = data.scope.to_string();
203171
let values = make_values_str(&[
204-
("refid", &def_id),
205-
("refidcrate", &def_crate),
206-
("declid", &dcn),
207-
("declidcrate", &dck),
172+
("refid", &ref_id),
173+
("declid", &decl_id),
208174
("scopeid", &scope)
209175
]);
210176

@@ -245,15 +211,11 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
245211
}
246212

247213
fn mod_ref(&mut self, data: ModRefData) {
248-
let (ref_id, ref_crate) = match data.ref_id {
249-
Some(rid) => (rid.index.as_usize().to_string(), rid.krate.to_string()),
250-
None => (0.to_string(), 0.to_string())
251-
};
214+
let ref_id = data.ref_id.unwrap_or(Id::null()).to_string();
252215

253216
let scope = data.scope.to_string();
254217
let values = make_values_str(&[
255218
("refid", &ref_id),
256-
("refidcrate", &ref_crate),
257219
("qualname", &data.qualname),
258220
("scopeid", &scope)
259221
]);
@@ -320,15 +282,10 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
320282
}
321283

322284
fn type_ref(&mut self, data: TypeRefData) {
323-
let (ref_id, ref_crate) = match data.ref_id {
324-
Some(id) => (id.index.as_usize().to_string(), id.krate.to_string()),
325-
None => (0.to_string(), 0.to_string())
326-
};
327-
285+
let ref_id = data.ref_id.unwrap_or(Id::null()).to_string();
328286
let scope = data.scope.to_string();
329287
let values = make_values_str(&[
330288
("refid", &ref_id),
331-
("refidcrate", &ref_crate),
332289
("qualname", &data.qualname),
333290
("scopeid", &scope)
334291
]);
@@ -348,16 +305,12 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
348305
}
349306

350307
fn use_data(&mut self, data: UseData) {
351-
let mod_id = data.mod_id.unwrap_or(null_def_id());
352-
353308
let id = data.id.to_string();
354-
let ref_id = mod_id.index.as_usize().to_string();
355-
let ref_crate = mod_id.krate.to_string();
309+
let mod_id = data.mod_id.unwrap_or(Id::null()).to_string();
356310
let scope = data.scope.to_string();
357311
let values = make_values_str(&[
358312
("id", &id),
359-
("refid", &ref_id),
360-
("refidcrate", &ref_crate),
313+
("mod_id", &mod_id),
361314
("name", &data.name),
362315
("scopeid", &scope)
363316
]);
@@ -395,12 +348,10 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
395348
}
396349

397350
fn variable_ref(&mut self, data: VariableRefData) {
398-
let ref_id = data.ref_id.index.as_usize().to_string();
399-
let ref_crate = data.ref_id.krate.to_string();
351+
let id = data.ref_id.to_string();
400352
let scope = data.scope.to_string();
401353
let values = make_values_str(&[
402-
("refid", &ref_id),
403-
("refidcrate", &ref_crate),
354+
("id", &id),
404355
("qualname", ""),
405356
("scopeid", &scope)
406357
]);
@@ -431,9 +382,9 @@ fn make_values_str(pairs: &[(&'static str, &str)]) -> String {
431382
})
432383
}
433384

434-
fn null_def_id() -> DefId {
435-
DefId {
436-
krate: 0,
437-
index: DefIndex::new(0),
438-
}
385+
fn span_extent_str(span: SpanData) -> String {
386+
format!("file_name,\"{}\",file_line,{},file_col,{},byte_start,{}\
387+
file_line_end,{},file_col_end,{},byte_end,{}",
388+
span.file_name, span.line_start, span.column_start, span.byte_start,
389+
span.line_end, span.column_end, span.byte_end)
439390
}

‎src/librustc_save_analysis/data.rs

+1-87
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,8 @@
1616
use std::hash::Hasher;
1717

1818
use rustc::hir::def_id::DefId;
19-
use rustc::ty;
2019
use syntax::ast::{CrateNum, NodeId};
21-
use syntax::codemap::{Span, CodeMap};
22-
23-
#[derive(Debug, Clone, RustcEncodable)]
24-
pub struct SpanData {
25-
file_name: String,
26-
byte_start: u32,
27-
byte_end: u32,
28-
/// 1-based.
29-
line_start: usize,
30-
line_end: usize,
31-
/// 1-based, character offset.
32-
column_start: usize,
33-
column_end: usize,
34-
}
35-
36-
impl SpanData {
37-
pub fn from_span(span: Span, cm: &CodeMap) -> SpanData {
38-
let start = cm.lookup_char_pos(span.lo);
39-
let end = cm.lookup_char_pos(span.hi);
40-
41-
SpanData {
42-
file_name: start.file.name.clone(),
43-
byte_start: span.lo.0,
44-
byte_end: span.hi.0,
45-
line_start: start.line,
46-
line_end: end.line,
47-
column_start: start.col.0 + 1,
48-
column_end: end.col.0 + 1,
49-
}
50-
}
51-
}
20+
use syntax::codemap::Span;
5221

5322
pub struct CrateData {
5423
pub name: String,
@@ -359,58 +328,3 @@ pub struct VariableRefData {
359328
pub scope: NodeId,
360329
pub ref_id: DefId,
361330
}
362-
363-
// Emitted ids are used to cross-reference items across crates. DefIds and
364-
// NodeIds do not usually correspond in any way. The strategy is to use the
365-
// index from the DefId as a crate-local id. However, within a crate, DefId
366-
// indices and NodeIds can overlap. So, we must adjust the NodeIds. If an
367-
// item can be identified by a DefId as well as a NodeId, then we use the
368-
// DefId index as the id. If it can't, then we have to use the NodeId, but
369-
// need to adjust it so it will not clash with any possible DefId index.
370-
pub fn normalize_node_id<'a>(tcx: &ty::TyCtxt<'a>, id: NodeId) -> usize {
371-
match tcx.map.opt_local_def_id(id) {
372-
Some(id) => id.index.as_usize(),
373-
None => id as usize + tcx.map.num_local_def_ids()
374-
}
375-
}
376-
377-
// Macro to implement a normalize() function (see below for usage)
378-
macro_rules! impl_normalize {
379-
($($t:ty => $($field:ident),*);*) => {
380-
$(
381-
impl $t {
382-
pub fn normalize<'a>(mut self, tcx: &ty::TyCtxt<'a>) -> $t {
383-
$(
384-
self.$field = normalize_node_id(tcx, self.$field) as u32;
385-
)*
386-
self
387-
}
388-
}
389-
)*
390-
}
391-
}
392-
393-
impl_normalize! {
394-
EnumData => id, scope;
395-
ExternCrateData => id, scope;
396-
FunctionCallData => scope;
397-
FunctionData => id, scope;
398-
FunctionRefData => scope;
399-
ImplData => id, scope;
400-
InheritanceData => deriv_id;
401-
MacroUseData => scope;
402-
MethodCallData => scope;
403-
MethodData => id, scope;
404-
ModData => id, scope;
405-
ModRefData => scope;
406-
StructData => ctor_id, id, scope;
407-
StructVariantData => id, scope;
408-
TupleVariantData => id, scope;
409-
TraitData => id, scope;
410-
TypedefData => id;
411-
TypeRefData => scope;
412-
UseData => id, scope;
413-
UseGlobData => id, scope;
414-
VariableData => id;
415-
VariableRefData => scope
416-
}

‎src/librustc_save_analysis/dump.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use super::data::*;
11+
use super::external_data::*;
1212

1313
pub trait Dump {
1414
fn crate_prelude(&mut self, CratePreludeData) {}

‎src/librustc_save_analysis/dump_visitor.rs

+54-57
Large diffs are not rendered by default.

‎src/librustc_save_analysis/external_data.rs

+640
Large diffs are not rendered by default.

‎src/librustc_save_analysis/json_dumper.rs

+8-577
Large diffs are not rendered by default.

‎src/librustc_save_analysis/lib.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@
2828
#[macro_use] extern crate syntax;
2929
extern crate serialize as rustc_serialize;
3030

31+
mod csv_dumper;
32+
mod json_dumper;
33+
mod data;
34+
mod dump;
35+
mod dump_visitor;
36+
pub mod external_data;
37+
#[macro_use]
38+
pub mod span_utils;
39+
3140
use rustc::hir;
3241
use rustc::hir::map::NodeItem;
3342
use rustc::hir::def::Def;
@@ -45,14 +54,6 @@ use syntax::parse::token::{self, keywords};
4554
use syntax::visit::{self, Visitor};
4655
use syntax::print::pprust::ty_to_string;
4756

48-
mod csv_dumper;
49-
mod json_dumper;
50-
mod data;
51-
mod dump;
52-
mod dump_visitor;
53-
#[macro_use]
54-
pub mod span_utils;
55-
5657
pub use self::csv_dumper::CsvDumper;
5758
pub use self::json_dumper::JsonDumper;
5859
pub use self::data::*;
@@ -748,7 +749,6 @@ pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>,
748749
root_path.pop();
749750
let output = &mut output_file;
750751

751-
let utils: SpanUtils<'tcx> = SpanUtils::new(&tcx.sess);
752752
let save_ctxt = SaveContext::new(tcx);
753753

754754
macro_rules! dump {
@@ -762,8 +762,8 @@ pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>,
762762
}
763763

764764
match format {
765-
Format::Csv => dump!(CsvDumper::new(output, utils)),
766-
Format::Json => dump!(JsonDumper::new(output, utils.sess.codemap())),
765+
Format::Csv => dump!(CsvDumper::new(output)),
766+
Format::Json => dump!(JsonDumper::new(output)),
767767
}
768768
}
769769

‎src/librustc_save_analysis/span_utils.rs

+2-21
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,8 @@ use std::path::Path;
1818

1919
use syntax::ast;
2020
use syntax::codemap::*;
21-
use syntax::parse::lexer;
22-
use syntax::parse::lexer::{Reader, StringReader};
23-
use syntax::parse::token;
24-
use syntax::parse::token::{keywords, Token};
21+
use syntax::parse::lexer::{self, Reader, StringReader};
22+
use syntax::parse::token::{self, keywords, Token};
2523

2624
#[derive(Clone)]
2725
pub struct SpanUtils<'a> {
@@ -48,23 +46,6 @@ impl<'a> SpanUtils<'a> {
4846
}
4947
}
5048

51-
// Standard string for extents/location.
52-
#[rustfmt_skip]
53-
pub fn extent_str(&self, span: Span) -> String {
54-
let lo_loc = self.sess.codemap().lookup_char_pos(span.lo);
55-
let hi_loc = self.sess.codemap().lookup_char_pos(span.hi);
56-
let lo_pos = self.sess.codemap().bytepos_to_file_charpos(span.lo);
57-
let hi_pos = self.sess.codemap().bytepos_to_file_charpos(span.hi);
58-
let lo_pos_byte = self.sess.codemap().lookup_byte_offset(span.lo).pos;
59-
let hi_pos_byte = self.sess.codemap().lookup_byte_offset(span.hi).pos;
60-
61-
format!("file_name,\"{}\",file_line,{},file_col,{},extent_start,{},extent_start_bytes,{},\
62-
file_line_end,{},file_col_end,{},extent_end,{},extent_end_bytes,{}",
63-
SpanUtils::make_path_string(&lo_loc.file.name),
64-
lo_loc.line, lo_loc.col.to_usize(), lo_pos.to_usize(), lo_pos_byte.to_usize(),
65-
hi_loc.line, hi_loc.col.to_usize(), hi_pos.to_usize(), hi_pos_byte.to_usize())
66-
}
67-
6849
// sub_span starts at span.lo, so we need to adjust the positions etc.
6950
// If sub_span is None, we don't need to adjust.
7051
pub fn make_sub_span(&self, span: Span, sub_span: Option<Span>) -> Option<Span> {

0 commit comments

Comments
 (0)
Please sign in to comment.