Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4751e45

Browse files
committedApr 28, 2016
Auto merge of #33208 - nrc:save-json, r=pnkfelix
save-analysis: dump in JSON format cc #18582
2 parents 0f9ba99 + 7ca2b94 commit 4751e45

File tree

12 files changed

+906
-281
lines changed

12 files changed

+906
-281
lines changed
 

‎mk/crates.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back rustc_mir
120120
log syntax serialize rustc_llvm rustc_platform_intrinsics \
121121
rustc_const_math rustc_const_eval rustc_incremental
122122
DEPS_rustc_incremental := rbml rustc serialize rustc_data_structures
123-
DEPS_rustc_save_analysis := rustc log syntax
123+
DEPS_rustc_save_analysis := rustc log syntax serialize
124124
DEPS_rustc_typeck := rustc syntax rustc_platform_intrinsics rustc_const_math \
125125
rustc_const_eval
126126

‎src/librustc/session/config.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
618618
ls: bool = (false, parse_bool,
619619
"list the symbols defined by a library crate"),
620620
save_analysis: bool = (false, parse_bool,
621-
"write syntax and type analysis information in addition to normal output"),
621+
"write syntax and type analysis (in JSON format) information in addition to normal output"),
622+
save_analysis_csv: bool = (false, parse_bool,
623+
"write syntax and type analysis (in CSV format) information in addition to normal output"),
622624
print_move_fragments: bool = (false, parse_bool,
623625
"print out move-fragment data for every fn"),
624626
flowgraph_print_loans: bool = (false, parse_bool,

‎src/librustc_driver/driver.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,7 @@ pub fn compile_input(sess: &Session,
141141
dep_graph));
142142

143143
// Discard MTWT tables that aren't required past lowering to HIR.
144-
if !sess.opts.debugging_opts.keep_mtwt_tables &&
145-
!sess.opts.debugging_opts.save_analysis {
144+
if !keep_mtwt_tables(sess) {
146145
syntax::ext::mtwt::clear_tables();
147146
}
148147

@@ -179,8 +178,7 @@ pub fn compile_input(sess: &Session,
179178
"early lint checks",
180179
|| lint::check_ast_crate(sess, &expanded_crate));
181180

182-
let opt_crate = if sess.opts.debugging_opts.keep_ast ||
183-
sess.opts.debugging_opts.save_analysis {
181+
let opt_crate = if keep_ast(sess) {
184182
Some(&expanded_crate)
185183
} else {
186184
drop(expanded_crate);
@@ -249,6 +247,18 @@ pub fn compile_input(sess: &Session,
249247
Ok(())
250248
}
251249

250+
fn keep_mtwt_tables(sess: &Session) -> bool {
251+
sess.opts.debugging_opts.keep_mtwt_tables ||
252+
sess.opts.debugging_opts.save_analysis ||
253+
sess.opts.debugging_opts.save_analysis_csv
254+
}
255+
256+
fn keep_ast(sess: &Session) -> bool {
257+
sess.opts.debugging_opts.keep_ast ||
258+
sess.opts.debugging_opts.save_analysis ||
259+
sess.opts.debugging_opts.save_analysis_csv
260+
}
261+
252262
/// The name used for source code that doesn't originate in a file
253263
/// (e.g. source from stdin or a string)
254264
pub fn anon_src() -> String {

‎src/librustc_driver/lib.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,15 +483,16 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
483483
control.after_llvm.stop = Compilation::Stop;
484484
}
485485

486-
if sess.opts.debugging_opts.save_analysis {
486+
if save_analysis(sess) {
487487
control.after_analysis.callback = box |state| {
488488
time(state.session.time_passes(), "save analysis", || {
489489
save::process_crate(state.tcx.unwrap(),
490490
state.lcx.unwrap(),
491491
state.krate.unwrap(),
492492
state.analysis.unwrap(),
493493
state.crate_name.unwrap(),
494-
state.out_dir)
494+
state.out_dir,
495+
save_analysis_format(state.session))
495496
});
496497
};
497498
control.after_analysis.run_callback_on_error = true;
@@ -502,6 +503,21 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
502503
}
503504
}
504505

506+
fn save_analysis(sess: &Session) -> bool {
507+
sess.opts.debugging_opts.save_analysis ||
508+
sess.opts.debugging_opts.save_analysis_csv
509+
}
510+
511+
fn save_analysis_format(sess: &Session) -> save::Format {
512+
if sess.opts.debugging_opts.save_analysis {
513+
save::Format::Json
514+
} else if sess.opts.debugging_opts.save_analysis_csv {
515+
save::Format::Csv
516+
} else {
517+
unreachable!();
518+
}
519+
}
520+
505521
impl RustcDefaultCalls {
506522
pub fn list_metadata(sess: &Session, matches: &getopts::Matches, input: &Input) -> Compilation {
507523
let r = matches.opt_strs("Z");

‎src/librustc_save_analysis/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ crate-type = ["dylib"]
1212
log = { path = "../liblog" }
1313
rustc = { path = "../librustc" }
1414
syntax = { path = "../libsyntax" }
15+
serialize = { path = "../libserialize" }

‎src/librustc_save_analysis/csv_dumper.rs

Lines changed: 27 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@ use super::span_utils::SpanUtils;
1919

2020
pub struct CsvDumper<'tcx, 'b, W: 'b> {
2121
output: &'b mut W,
22-
dump_spans: bool,
2322
span: SpanUtils<'tcx>
2423
}
2524

2625
impl<'a, 'b, W: Write> CsvDumper<'a, 'b, W> {
2726
pub fn new(writer: &'b mut W, span: SpanUtils<'a>) -> CsvDumper<'a, 'b, W> {
28-
CsvDumper { output: writer, dump_spans: false, span: span }
27+
CsvDumper { output: writer, span: span }
2928
}
3029

3130
fn record(&mut self, kind: &str, span: Span, values: String) {
@@ -40,36 +39,23 @@ impl<'a, 'b, W: Write> CsvDumper<'a, 'b, W> {
4039
error!("Error writing output '{}'", info);
4140
}
4241
}
43-
44-
pub fn dump_span(&mut self, kind: &str, span: Span) {
45-
assert!(self.dump_spans);
46-
let result = format!("span,kind,{},{},text,\"{}\"\n",
47-
kind,
48-
self.span.extent_str(span),
49-
escape(self.span.snippet(span)));
50-
self.record_raw(&result);
51-
}
5242
}
5343

5444
impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
55-
fn crate_prelude(&mut self, span: Span, data: CratePreludeData) {
56-
let crate_root = data.crate_root.unwrap_or("<no source>".to_owned());
57-
45+
fn crate_prelude(&mut self, data: CratePreludeData) {
5846
let values = make_values_str(&[
5947
("name", &data.crate_name),
60-
("crate_root", &crate_root)
48+
("crate_root", &data.crate_root)
6149
]);
6250

63-
self.record("crate", span, values);
51+
self.record("crate", data.span, values);
6452

6553
for c in data.external_crates {
6654
let num = c.num.to_string();
67-
let lo_loc = self.span.sess.codemap().lookup_char_pos(span.lo);
68-
let file_name = SpanUtils::make_path_string(&lo_loc.file.name);
6955
let values = make_values_str(&[
7056
("name", &c.name),
7157
("crate", &num),
72-
("file_name", &file_name)
58+
("file_name", &c.file_name)
7359
]);
7460

7561
self.record_raw(&format!("external_crate{}\n", values));
@@ -78,12 +64,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
7864
self.record_raw("end_external_crates\n");
7965
}
8066

81-
fn enum_data(&mut self, span: Span, data: EnumData) {
82-
if self.dump_spans {
83-
self.dump_span("enum", span);
84-
return;
85-
}
86-
67+
fn enum_data(&mut self, data: EnumData) {
8768
let id = data.id.to_string();
8869
let scope = data.scope.to_string();
8970
let values = make_values_str(&[
@@ -96,12 +77,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
9677
self.record("enum", data.span, values);
9778
}
9879

99-
fn extern_crate(&mut self, span: Span, data: ExternCrateData) {
100-
if self.dump_spans {
101-
self.dump_span("extern_crate", span);
102-
return;
103-
}
104-
80+
fn extern_crate(&mut self, data: ExternCrateData) {
10581
let id = data.id.to_string();
10682
let crate_num = data.crate_num.to_string();
10783
let scope = data.scope.to_string();
@@ -116,12 +92,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
11692
self.record("extern_crate", data.span, values);
11793
}
11894

119-
fn impl_data(&mut self, span: Span, data: ImplData) {
120-
if self.dump_spans {
121-
self.dump_span("impl", span);
122-
return;
123-
}
124-
95+
fn impl_data(&mut self, data: ImplData) {
12596
let self_ref = data.self_ref.unwrap_or(null_def_id());
12697
let trait_ref = data.trait_ref.unwrap_or(null_def_id());
12798

@@ -144,10 +115,6 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
144115
}
145116

146117
fn inheritance(&mut self, data: InheritanceData) {
147-
if self.dump_spans {
148-
return;
149-
}
150-
151118
let base_id = data.base_id.index.as_usize().to_string();
152119
let base_crate = data.base_id.krate.to_string();
153120
let deriv_id = data.deriv_id.to_string();
@@ -162,12 +129,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
162129
self.record("inheritance", data.span, values);
163130
}
164131

165-
fn function(&mut self, span: Span, data: FunctionData) {
166-
if self.dump_spans {
167-
self.dump_span("function", span);
168-
return;
169-
}
170-
132+
fn function(&mut self, data: FunctionData) {
171133
let (decl_id, decl_crate) = match data.declaration {
172134
Some(id) => (id.index.as_usize().to_string(), id.krate.to_string()),
173135
None => (String::new(), String::new())
@@ -186,12 +148,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
186148
self.record("function", data.span, values);
187149
}
188150

189-
fn function_ref(&mut self, span: Span, data: FunctionRefData) {
190-
if self.dump_spans {
191-
self.dump_span("fn_ref", span);
192-
return;
193-
}
194-
151+
fn function_ref(&mut self, data: FunctionRefData) {
195152
let ref_id = data.ref_id.index.as_usize().to_string();
196153
let ref_crate = data.ref_id.krate.to_string();
197154
let scope = data.scope.to_string();
@@ -205,12 +162,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
205162
self.record("fn_ref", data.span, values);
206163
}
207164

208-
fn function_call(&mut self, span: Span, data: FunctionCallData) {
209-
if self.dump_spans {
210-
self.dump_span("fn_call", span);
211-
return;
212-
}
213-
165+
fn function_call(&mut self, data: FunctionCallData) {
214166
let ref_id = data.ref_id.index.as_usize().to_string();
215167
let ref_crate = data.ref_id.krate.to_string();
216168
let qualname = String::new();
@@ -225,12 +177,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
225177
self.record("fn_call", data.span, values);
226178
}
227179

228-
fn method(&mut self, span: Span, data: MethodData) {
229-
if self.dump_spans {
230-
self.dump_span("method_decl", span);
231-
return;
232-
}
233-
180+
fn method(&mut self, data: MethodData) {
234181
let id = data.id.to_string();
235182
let scope = data.scope.to_string();
236183
let values = make_values_str(&[
@@ -239,15 +186,10 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
239186
("scopeid", &scope)
240187
]);
241188

242-
self.record("method_decl", span, values);
189+
self.record("method_decl", data.span, values);
243190
}
244191

245-
fn method_call(&mut self, span: Span, data: MethodCallData) {
246-
if self.dump_spans {
247-
self.dump_span("method_call", span);
248-
return;
249-
}
250-
192+
fn method_call(&mut self, data: MethodCallData) {
251193
let (dcn, dck) = match data.decl_id {
252194
Some(declid) => (declid.index.as_usize().to_string(), declid.krate.to_string()),
253195
None => (String::new(), String::new()),
@@ -269,12 +211,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
269211
self.record("method_call", data.span, values);
270212
}
271213

272-
fn macro_data(&mut self, span: Span, data: MacroData) {
273-
if self.dump_spans {
274-
self.dump_span("macro", span);
275-
return;
276-
}
277-
214+
fn macro_data(&mut self, data: MacroData) {
278215
let values = make_values_str(&[
279216
("name", &data.name),
280217
("qualname", &data.qualname)
@@ -283,12 +220,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
283220
self.record("macro", data.span, values);
284221
}
285222

286-
fn macro_use(&mut self, span: Span, data: MacroUseData) {
287-
if self.dump_spans {
288-
self.dump_span("macro_use", span);
289-
return;
290-
}
291-
223+
fn macro_use(&mut self, data: MacroUseData) {
292224
let scope = data.scope.to_string();
293225
let values = make_values_str(&[
294226
("callee_name", &data.name),
@@ -300,10 +232,6 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
300232
}
301233

302234
fn mod_data(&mut self, data: ModData) {
303-
if self.dump_spans {
304-
return;
305-
}
306-
307235
let id = data.id.to_string();
308236
let scope = data.scope.to_string();
309237
let values = make_values_str(&[
@@ -316,12 +244,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
316244
self.record("module", data.span, values);
317245
}
318246

319-
fn mod_ref(&mut self, span: Span, data: ModRefData) {
320-
if self.dump_spans {
321-
self.dump_span("mod_ref", span);
322-
return;
323-
}
324-
247+
fn mod_ref(&mut self, data: ModRefData) {
325248
let (ref_id, ref_crate) = match data.ref_id {
326249
Some(rid) => (rid.index.as_usize().to_string(), rid.krate.to_string()),
327250
None => (0.to_string(), 0.to_string())
@@ -338,12 +261,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
338261
self.record("mod_ref", data.span, values);
339262
}
340263

341-
fn struct_data(&mut self, span: Span, data: StructData) {
342-
if self.dump_spans {
343-
self.dump_span("struct", span);
344-
return;
345-
}
346-
264+
fn struct_data(&mut self, data: StructData) {
347265
let id = data.id.to_string();
348266
let ctor_id = data.ctor_id.to_string();
349267
let scope = data.scope.to_string();
@@ -358,12 +276,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
358276
self.record("struct", data.span, values);
359277
}
360278

361-
fn struct_variant(&mut self, span: Span, data: StructVariantData) {
362-
if self.dump_spans {
363-
self.dump_span("variant_struct", span);
364-
return;
365-
}
366-
279+
fn struct_variant(&mut self, data: StructVariantData) {
367280
let id = data.id.to_string();
368281
let scope = data.scope.to_string();
369282
let values = make_values_str(&[
@@ -378,12 +291,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
378291
self.record("variant_struct", data.span, values);
379292
}
380293

381-
fn trait_data(&mut self, span: Span, data: TraitData) {
382-
if self.dump_spans {
383-
self.dump_span("trait", span);
384-
return;
385-
}
386-
294+
fn trait_data(&mut self, data: TraitData) {
387295
let id = data.id.to_string();
388296
let scope = data.scope.to_string();
389297
let values = make_values_str(&[
@@ -396,12 +304,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
396304
self.record("trait", data.span, values);
397305
}
398306

399-
fn tuple_variant(&mut self, span: Span, data: TupleVariantData) {
400-
if self.dump_spans {
401-
self.dump_span("variant", span);
402-
return;
403-
}
404-
307+
fn tuple_variant(&mut self, data: TupleVariantData) {
405308
let id = data.id.to_string();
406309
let scope = data.scope.to_string();
407310
let values = make_values_str(&[
@@ -416,12 +319,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
416319
self.record("variant", data.span, values);
417320
}
418321

419-
fn type_ref(&mut self, span: Span, data: TypeRefData) {
420-
if self.dump_spans {
421-
self.dump_span("type_ref", span);
422-
return;
423-
}
424-
322+
fn type_ref(&mut self, data: TypeRefData) {
425323
let (ref_id, ref_crate) = match data.ref_id {
426324
Some(id) => (id.index.as_usize().to_string(), id.krate.to_string()),
427325
None => (0.to_string(), 0.to_string())
@@ -438,12 +336,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
438336
self.record("type_ref", data.span, values);
439337
}
440338

441-
fn typedef(&mut self, span: Span, data: TypedefData) {
442-
if self.dump_spans {
443-
self.dump_span("typedef", span);
444-
return;
445-
}
446-
339+
fn typedef(&mut self, data: TypedefData) {
447340
let id = data.id.to_string();
448341
let values = make_values_str(&[
449342
("id", &id),
@@ -454,12 +347,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
454347
self.record("typedef", data.span, values);
455348
}
456349

457-
fn use_data(&mut self, span: Span, data: UseData) {
458-
if self.dump_spans {
459-
self.dump_span("use_alias", span);
460-
return;
461-
}
462-
350+
fn use_data(&mut self, data: UseData) {
463351
let mod_id = data.mod_id.unwrap_or(null_def_id());
464352

465353
let id = data.id.to_string();
@@ -477,12 +365,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
477365
self.record("use_alias", data.span, values);
478366
}
479367

480-
fn use_glob(&mut self, span: Span, data: UseGlobData) {
481-
if self.dump_spans {
482-
self.dump_span("use_glob", span);
483-
return;
484-
}
485-
368+
fn use_glob(&mut self, data: UseGlobData) {
486369
let names = data.names.join(", ");
487370

488371
let id = data.id.to_string();
@@ -496,12 +379,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
496379
self.record("use_glob", data.span, values);
497380
}
498381

499-
fn variable(&mut self, span: Span, data: VariableData) {
500-
if self.dump_spans {
501-
self.dump_span("variable", span);
502-
return;
503-
}
504-
382+
fn variable(&mut self, data: VariableData) {
505383
let id = data.id.to_string();
506384
let scope = data.scope.to_string();
507385
let values = make_values_str(&[
@@ -516,12 +394,7 @@ impl<'a, 'b, W: Write + 'b> Dump for CsvDumper<'a, 'b, W> {
516394
self.record("variable", data.span, values);
517395
}
518396

519-
fn variable_ref(&mut self, span: Span, data: VariableRefData) {
520-
if self.dump_spans {
521-
self.dump_span("var_ref", span);
522-
return;
523-
}
524-
397+
fn variable_ref(&mut self, data: VariableRefData) {
525398
let ref_id = data.ref_id.index.as_usize().to_string();
526399
let ref_crate = data.ref_id.krate.to_string();
527400
let scope = data.scope.to_string();

‎src/librustc_save_analysis/data.rs

Lines changed: 64 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,47 @@ use std::hash::Hasher;
1818
use rustc::hir::def_id::DefId;
1919
use rustc::ty;
2020
use syntax::ast::{CrateNum, NodeId};
21-
use syntax::codemap::Span;
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+
}
2252

2353
pub struct CrateData {
2454
pub name: String,
2555
pub number: u32,
56+
pub span: Span,
2657
}
2758

2859
/// Data for any entity in the Rust language. The actual data contained varies
2960
/// with the kind of entity being queried. See the nested structs for details.
30-
#[derive(Debug)]
61+
#[derive(Debug, RustcEncodable)]
3162
pub enum Data {
3263
/// Data for Enums.
3364
EnumData(EnumData),
@@ -79,22 +110,24 @@ pub enum Data {
79110
}
80111

81112
/// Data for the prelude of a crate.
82-
#[derive(Debug)]
113+
#[derive(Debug, RustcEncodable)]
83114
pub struct CratePreludeData {
84115
pub crate_name: String,
85-
pub crate_root: Option<String>,
86-
pub external_crates: Vec<ExternalCrateData>
116+
pub crate_root: String,
117+
pub external_crates: Vec<ExternalCrateData>,
118+
pub span: Span,
87119
}
88120

89121
/// Data for external crates in the prelude of a crate.
90-
#[derive(Debug)]
122+
#[derive(Debug, RustcEncodable)]
91123
pub struct ExternalCrateData {
92124
pub name: String,
93-
pub num: CrateNum
125+
pub num: CrateNum,
126+
pub file_name: String,
94127
}
95128

96129
/// Data for enum declarations.
97-
#[derive(Clone, Debug)]
130+
#[derive(Clone, Debug, RustcEncodable)]
98131
pub struct EnumData {
99132
pub id: NodeId,
100133
pub value: String,
@@ -104,7 +137,7 @@ pub struct EnumData {
104137
}
105138

106139
/// Data for extern crates.
107-
#[derive(Debug)]
140+
#[derive(Debug, RustcEncodable)]
108141
pub struct ExternCrateData {
109142
pub id: NodeId,
110143
pub name: String,
@@ -115,15 +148,15 @@ pub struct ExternCrateData {
115148
}
116149

117150
/// Data about a function call.
118-
#[derive(Debug)]
151+
#[derive(Debug, RustcEncodable)]
119152
pub struct FunctionCallData {
120153
pub span: Span,
121154
pub scope: NodeId,
122155
pub ref_id: DefId,
123156
}
124157

125158
/// Data for all kinds of functions and methods.
126-
#[derive(Clone, Debug)]
159+
#[derive(Clone, Debug, RustcEncodable)]
127160
pub struct FunctionData {
128161
pub id: NodeId,
129162
pub name: String,
@@ -134,14 +167,14 @@ pub struct FunctionData {
134167
}
135168

136169
/// Data about a function call.
137-
#[derive(Debug)]
170+
#[derive(Debug, RustcEncodable)]
138171
pub struct FunctionRefData {
139172
pub span: Span,
140173
pub scope: NodeId,
141174
pub ref_id: DefId,
142175
}
143176

144-
#[derive(Debug)]
177+
#[derive(Debug, RustcEncodable)]
145178
pub struct ImplData {
146179
pub id: NodeId,
147180
pub span: Span,
@@ -150,7 +183,7 @@ pub struct ImplData {
150183
pub self_ref: Option<DefId>,
151184
}
152185

153-
#[derive(Debug)]
186+
#[derive(Debug, RustcEncodable)]
154187
// FIXME: this struct should not exist. However, removing it requires heavy
155188
// refactoring of dump_visitor.rs. See PR 31838 for more info.
156189
pub struct ImplData2 {
@@ -164,23 +197,23 @@ pub struct ImplData2 {
164197
pub self_ref: Option<TypeRefData>,
165198
}
166199

167-
#[derive(Debug)]
200+
#[derive(Debug, RustcEncodable)]
168201
pub struct InheritanceData {
169202
pub span: Span,
170203
pub base_id: DefId,
171204
pub deriv_id: NodeId
172205
}
173206

174207
/// Data about a macro declaration.
175-
#[derive(Debug)]
208+
#[derive(Debug, RustcEncodable)]
176209
pub struct MacroData {
177210
pub span: Span,
178211
pub name: String,
179212
pub qualname: String,
180213
}
181214

182215
/// Data about a macro use.
183-
#[derive(Debug)]
216+
#[derive(Debug, RustcEncodable)]
184217
pub struct MacroUseData {
185218
pub span: Span,
186219
pub name: String,
@@ -193,7 +226,7 @@ pub struct MacroUseData {
193226
}
194227

195228
/// Data about a method call.
196-
#[derive(Debug)]
229+
#[derive(Debug, RustcEncodable)]
197230
pub struct MethodCallData {
198231
pub span: Span,
199232
pub scope: NodeId,
@@ -202,7 +235,7 @@ pub struct MethodCallData {
202235
}
203236

204237
/// Data for method declarations (methods with a body are treated as functions).
205-
#[derive(Clone, Debug)]
238+
#[derive(Clone, Debug, RustcEncodable)]
206239
pub struct MethodData {
207240
pub id: NodeId,
208241
pub qualname: String,
@@ -211,7 +244,7 @@ pub struct MethodData {
211244
}
212245

213246
/// Data for modules.
214-
#[derive(Debug)]
247+
#[derive(Debug, RustcEncodable)]
215248
pub struct ModData {
216249
pub id: NodeId,
217250
pub name: String,
@@ -222,15 +255,15 @@ pub struct ModData {
222255
}
223256

224257
/// Data for a reference to a module.
225-
#[derive(Debug)]
258+
#[derive(Debug, RustcEncodable)]
226259
pub struct ModRefData {
227260
pub span: Span,
228261
pub scope: NodeId,
229262
pub ref_id: Option<DefId>,
230263
pub qualname: String
231264
}
232265

233-
#[derive(Debug)]
266+
#[derive(Debug, RustcEncodable)]
234267
pub struct StructData {
235268
pub span: Span,
236269
pub id: NodeId,
@@ -240,7 +273,7 @@ pub struct StructData {
240273
pub value: String
241274
}
242275

243-
#[derive(Debug)]
276+
#[derive(Debug, RustcEncodable)]
244277
pub struct StructVariantData {
245278
pub span: Span,
246279
pub id: NodeId,
@@ -250,7 +283,7 @@ pub struct StructVariantData {
250283
pub scope: NodeId
251284
}
252285

253-
#[derive(Debug)]
286+
#[derive(Debug, RustcEncodable)]
254287
pub struct TraitData {
255288
pub span: Span,
256289
pub id: NodeId,
@@ -259,7 +292,7 @@ pub struct TraitData {
259292
pub value: String
260293
}
261294

262-
#[derive(Debug)]
295+
#[derive(Debug, RustcEncodable)]
263296
pub struct TupleVariantData {
264297
pub span: Span,
265298
pub id: NodeId,
@@ -271,7 +304,7 @@ pub struct TupleVariantData {
271304
}
272305

273306
/// Data for a typedef.
274-
#[derive(Debug)]
307+
#[derive(Debug, RustcEncodable)]
275308
pub struct TypedefData {
276309
pub id: NodeId,
277310
pub span: Span,
@@ -280,15 +313,15 @@ pub struct TypedefData {
280313
}
281314

282315
/// Data for a reference to a type or trait.
283-
#[derive(Clone, Debug)]
316+
#[derive(Clone, Debug, RustcEncodable)]
284317
pub struct TypeRefData {
285318
pub span: Span,
286319
pub scope: NodeId,
287320
pub ref_id: Option<DefId>,
288321
pub qualname: String,
289322
}
290323

291-
#[derive(Debug)]
324+
#[derive(Debug, RustcEncodable)]
292325
pub struct UseData {
293326
pub id: NodeId,
294327
pub span: Span,
@@ -297,7 +330,7 @@ pub struct UseData {
297330
pub scope: NodeId
298331
}
299332

300-
#[derive(Debug)]
333+
#[derive(Debug, RustcEncodable)]
301334
pub struct UseGlobData {
302335
pub id: NodeId,
303336
pub span: Span,
@@ -306,7 +339,7 @@ pub struct UseGlobData {
306339
}
307340

308341
/// Data for local and global variables (consts and statics).
309-
#[derive(Debug)]
342+
#[derive(Debug, RustcEncodable)]
310343
pub struct VariableData {
311344
pub id: NodeId,
312345
pub name: String,
@@ -319,7 +352,7 @@ pub struct VariableData {
319352

320353
/// Data for the use of some item (e.g., the use of a local variable, which
321354
/// will refer to that variables declaration (by ref_id)).
322-
#[derive(Debug)]
355+
#[derive(Debug, RustcEncodable)]
323356
pub struct VariableRefData {
324357
pub name: String,
325358
pub span: Span,

‎src/librustc_save_analysis/dump.rs

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,31 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
use syntax::codemap::Span;
12-
1311
use super::data::*;
1412

1513
pub trait Dump {
16-
fn crate_prelude(&mut self, _: Span, _: CratePreludeData) {}
17-
fn enum_data(&mut self, _: Span, _: EnumData) {}
18-
fn extern_crate(&mut self, _: Span, _: ExternCrateData) {}
19-
fn impl_data(&mut self, _: Span, _: ImplData) {}
20-
fn inheritance(&mut self, _: InheritanceData) {}
21-
fn function(&mut self, _: Span, _: FunctionData) {}
22-
fn function_ref(&mut self, _: Span, _: FunctionRefData) {}
23-
fn function_call(&mut self, _: Span, _: FunctionCallData) {}
24-
fn method(&mut self, _: Span, _: MethodData) {}
25-
fn method_call(&mut self, _: Span, _: MethodCallData) {}
26-
fn macro_data(&mut self, _: Span, _: MacroData) {}
27-
fn macro_use(&mut self, _: Span, _: MacroUseData) {}
28-
fn mod_data(&mut self, _: ModData) {}
29-
fn mod_ref(&mut self, _: Span, _: ModRefData) {}
30-
fn struct_data(&mut self, _: Span, _: StructData) {}
31-
fn struct_variant(&mut self, _: Span, _: StructVariantData) {}
32-
fn trait_data(&mut self, _: Span, _: TraitData) {}
33-
fn tuple_variant(&mut self, _: Span, _: TupleVariantData) {}
34-
fn type_ref(&mut self, _: Span, _: TypeRefData) {}
35-
fn typedef(&mut self, _: Span, _: TypedefData) {}
36-
fn use_data(&mut self, _: Span, _: UseData) {}
37-
fn use_glob(&mut self, _: Span, _: UseGlobData) {}
38-
fn variable(&mut self, _: Span, _: VariableData) {}
39-
fn variable_ref(&mut self, _: Span, _: VariableRefData) {}
14+
fn crate_prelude(&mut self, CratePreludeData) {}
15+
fn enum_data(&mut self, EnumData) {}
16+
fn extern_crate(&mut self, ExternCrateData) {}
17+
fn impl_data(&mut self, ImplData) {}
18+
fn inheritance(&mut self, InheritanceData) {}
19+
fn function(&mut self, FunctionData) {}
20+
fn function_ref(&mut self, FunctionRefData) {}
21+
fn function_call(&mut self, FunctionCallData) {}
22+
fn method(&mut self, MethodData) {}
23+
fn method_call(&mut self, MethodCallData) {}
24+
fn macro_data(&mut self, MacroData) {}
25+
fn macro_use(&mut self, MacroUseData) {}
26+
fn mod_data(&mut self, ModData) {}
27+
fn mod_ref(&mut self, ModRefData) {}
28+
fn struct_data(&mut self, StructData) {}
29+
fn struct_variant(&mut self, StructVariantData) {}
30+
fn trait_data(&mut self, TraitData) {}
31+
fn tuple_variant(&mut self, TupleVariantData) {}
32+
fn type_ref(&mut self, TypeRefData) {}
33+
fn typedef(&mut self, TypedefData) {}
34+
fn use_data(&mut self, UseData) {}
35+
fn use_glob(&mut self, UseGlobData) {}
36+
fn variable(&mut self, VariableData) {}
37+
fn variable_ref(&mut self, VariableRefData) {}
4038
}

‎src/librustc_save_analysis/dump_visitor.rs

Lines changed: 55 additions & 52 deletions
Large diffs are not rendered by default.

‎src/librustc_save_analysis/json_dumper.rs

Lines changed: 651 additions & 0 deletions
Large diffs are not rendered by default.

‎src/librustc_save_analysis/lib.rs

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#[macro_use] extern crate log;
2828
#[macro_use] extern crate syntax;
29+
extern crate serialize as rustc_serialize;
2930

3031
use rustc::hir::{self, lowering};
3132
use rustc::hir::map::NodeItem;
@@ -45,13 +46,15 @@ use syntax::visit::{self, Visitor};
4546
use syntax::print::pprust::ty_to_string;
4647

4748
mod csv_dumper;
49+
mod json_dumper;
4850
mod data;
4951
mod dump;
5052
mod dump_visitor;
5153
#[macro_use]
5254
pub mod span_utils;
5355

5456
pub use self::csv_dumper::CsvDumper;
57+
pub use self::json_dumper::JsonDumper;
5558
pub use self::data::*;
5659
pub use self::dump::Dump;
5760
pub use self::dump_visitor::DumpVisitor;
@@ -104,9 +107,17 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
104107
let mut result = Vec::new();
105108

106109
for n in self.tcx.sess.cstore.crates() {
110+
let span = match self.tcx.sess.cstore.extern_crate(n) {
111+
Some(ref c) => c.span,
112+
None => {
113+
debug!("Skipping crate {}, no data", n);
114+
continue;
115+
}
116+
};
107117
result.push(CrateData {
108118
name: (&self.tcx.sess.cstore.crate_name(n)[..]).to_owned(),
109119
number: n,
120+
span: span,
110121
});
111122
}
112123

@@ -677,24 +688,40 @@ impl<'v> Visitor<'v> for PathCollector {
677688
}
678689
}
679690

691+
#[derive(Clone, Copy, Debug)]
692+
pub enum Format {
693+
Csv,
694+
Json,
695+
}
696+
697+
impl Format {
698+
fn extension(&self) -> &'static str {
699+
match *self {
700+
Format::Csv => ".csv",
701+
Format::Json => ".json",
702+
}
703+
}
704+
}
705+
680706
pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>,
681707
lcx: &'l lowering::LoweringContext<'l>,
682708
krate: &ast::Crate,
683709
analysis: &'l ty::CrateAnalysis<'l>,
684710
cratename: &str,
685-
odir: Option<&Path>) {
711+
odir: Option<&Path>,
712+
format: Format) {
686713
let _ignore = tcx.dep_graph.in_ignore();
687714

688715
assert!(analysis.glob_map.is_some());
689716

690717
info!("Dumping crate {}", cratename);
691718

692719
// find a path to dump our data to
693-
let mut root_path = match env::var_os("DXR_RUST_TEMP_FOLDER") {
720+
let mut root_path = match env::var_os("RUST_SAVE_ANALYSIS_FOLDER") {
694721
Some(val) => PathBuf::from(val),
695722
None => match odir {
696-
Some(val) => val.join("dxr"),
697-
None => PathBuf::from("dxr-temp"),
723+
Some(val) => val.join("save-analysis"),
724+
None => PathBuf::from("save-analysis-temp"),
698725
},
699726
};
700727

@@ -718,22 +745,32 @@ pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>,
718745
};
719746
out_name.push_str(&cratename);
720747
out_name.push_str(&tcx.sess.opts.cg.extra_filename);
721-
out_name.push_str(".csv");
748+
out_name.push_str(format.extension());
722749
root_path.push(&out_name);
723750
let mut output_file = File::create(&root_path).unwrap_or_else(|e| {
724751
let disp = root_path.display();
725752
tcx.sess.fatal(&format!("Could not open {}: {}", disp, e));
726753
});
727754
root_path.pop();
755+
let output = &mut output_file;
728756

729757
let utils: SpanUtils<'tcx> = SpanUtils::new(&tcx.sess);
730758
let save_ctxt = SaveContext::new(tcx, lcx);
731-
let mut dumper = CsvDumper::new(&mut output_file, utils);
732-
let mut visitor = DumpVisitor::new(tcx, save_ctxt, analysis, &mut dumper);
733-
// FIXME: we don't write anything!
734759

735-
visitor.dump_crate_info(cratename, krate);
736-
visit::walk_crate(&mut visitor, krate);
760+
macro_rules! dump {
761+
($new_dumper: expr) => {{
762+
let mut dumper = $new_dumper;
763+
let mut visitor = DumpVisitor::new(tcx, save_ctxt, analysis, &mut dumper);
764+
765+
visitor.dump_crate_info(cratename, krate);
766+
visit::walk_crate(&mut visitor, krate);
767+
}}
768+
}
769+
770+
match format {
771+
Format::Csv => dump!(CsvDumper::new(output, utils)),
772+
Format::Json => dump!(JsonDumper::new(output, utils.sess.codemap())),
773+
}
737774
}
738775

739776
// Utility functions for the module.

‎src/test/run-make/save-analysis/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ all: code
33
krate2: krate2.rs
44
$(RUSTC) $<
55
code: foo.rs krate2
6+
$(RUSTC) foo.rs -Zsave-analysis-csv
67
$(RUSTC) foo.rs -Zsave-analysis

0 commit comments

Comments
 (0)
Please sign in to comment.