1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 use rustc
::hir
::def_id
::{DefId, DefIndex}
;
14 use syntax
::codemap
::Span
;
17 use super::dump
::Dump
;
18 use super::span_utils
::SpanUtils
;
20 pub struct CsvDumper
<'a
, 'b
, W
: 'b
> {
26 impl<'a
, 'b
, W
: Write
> CsvDumper
<'a
, 'b
, W
> {
27 pub fn new(writer
: &'b
mut W
, span
: SpanUtils
<'a
>) -> CsvDumper
<'a
, 'b
, W
> {
28 CsvDumper { output: writer, dump_spans: false, span: span }
31 fn record(&mut self, kind
: &str, span
: Span
, values
: String
) {
32 let span_str
= self.span
.extent_str(span
);
33 if let Err(_
) = write
!(self.output
, "{},{}{}\n", kind
, span_str
, values
) {
34 error
!("Error writing output");
38 fn record_raw(&mut self, info
: &str) {
39 if let Err(_
) = write
!(self.output
, "{}", info
) {
40 error
!("Error writing output '{}'", info
);
44 pub fn dump_span(&mut self, kind
: &str, span
: Span
) {
45 assert
!(self.dump_spans
);
46 let result
= format
!("span,kind,{},{},text,\"{}\"\n",
48 self.span
.extent_str(span
),
49 escape(self.span
.snippet(span
)));
50 self.record_raw(&result
);
54 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());
58 let values
= make_values_str(&[
59 ("name", &data
.crate_name
),
60 ("crate_root", &crate_root
)
63 self.record("crate", span
, values
);
65 for c
in data
.external_crates
{
66 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
);
69 let values
= make_values_str(&[
72 ("file_name", &file_name
)
75 self.record_raw(&format
!("external_crate{}\n", values
));
78 self.record_raw("end_external_crates\n");
81 fn enum_data(&mut self, span
: Span
, data
: EnumData
) {
83 self.dump_span("enum", span
);
87 let id
= data
.id
.to_string();
88 let scope
= data
.scope
.to_string();
89 let values
= make_values_str(&[
91 ("qualname", &data
.qualname
),
93 ("value", &data
.value
)
96 self.record("enum", data
.span
, values
);
99 fn extern_crate(&mut self, span
: Span
, data
: ExternCrateData
) {
101 self.dump_span("extern_crate", span
);
105 let id
= data
.id
.to_string();
106 let crate_num
= data
.crate_num
.to_string();
107 let scope
= data
.scope
.to_string();
108 let values
= make_values_str(&[
110 ("name", &data
.name
),
111 ("location", &data
.location
),
112 ("crate", &crate_num
),
116 self.record("extern_crate", data
.span
, values
);
119 fn impl_data(&mut self, span
: Span
, data
: ImplData
) {
121 self.dump_span("impl", span
);
125 let self_ref
= data
.self_ref
.unwrap_or(null_def_id());
126 let trait_ref
= data
.trait_ref
.unwrap_or(null_def_id());
128 let id
= data
.id
.to_string();
129 let ref_id
= self_ref
.index
.as_usize().to_string();
130 let ref_id_crate
= self_ref
.krate
.to_string();
131 let trait_id
= trait_ref
.index
.as_usize().to_string();
132 let trait_id_crate
= trait_ref
.krate
.to_string();
133 let scope
= data
.scope
.to_string();
134 let values
= make_values_str(&[
137 ("refidcrate", &ref_id_crate
),
138 ("traitid", &trait_id
),
139 ("traitidcrate", &trait_id_crate
),
143 self.record("impl", data
.span
, values
);
146 fn inheritance(&mut self, data
: InheritanceData
) {
151 let base_id
= data
.base_id
.index
.as_usize().to_string();
152 let base_crate
= data
.base_id
.krate
.to_string();
153 let deriv_id
= data
.deriv_id
.to_string();
154 let deriv_crate
= 0.to_string();
155 let values
= make_values_str(&[
157 ("basecrate", &base_crate
),
158 ("derived", &deriv_id
),
159 ("derivedcrate", &deriv_crate
)
162 self.record("inheritance", data
.span
, values
);
165 fn function(&mut self, span
: Span
, data
: FunctionData
) {
167 self.dump_span("function", span
);
171 let (decl_id
, decl_crate
) = match data
.declaration
{
172 Some(id
) => (id
.index
.as_usize().to_string(), id
.krate
.to_string()),
173 None
=> (String
::new(), String
::new())
176 let id
= data
.id
.to_string();
177 let scope
= data
.scope
.to_string();
178 let values
= make_values_str(&[
180 ("qualname", &data
.qualname
),
181 ("declid", &decl_id
),
182 ("declidcrate", &decl_crate
),
186 self.record("function", data
.span
, values
);
189 fn function_ref(&mut self, span
: Span
, data
: FunctionRefData
) {
191 self.dump_span("fn_ref", span
);
195 let ref_id
= data
.ref_id
.index
.as_usize().to_string();
196 let ref_crate
= data
.ref_id
.krate
.to_string();
197 let scope
= data
.scope
.to_string();
198 let values
= make_values_str(&[
200 ("refidcrate", &ref_crate
),
205 self.record("fn_ref", data
.span
, values
);
208 fn function_call(&mut self, span
: Span
, data
: FunctionCallData
) {
210 self.dump_span("fn_call", span
);
214 let ref_id
= data
.ref_id
.index
.as_usize().to_string();
215 let ref_crate
= data
.ref_id
.krate
.to_string();
216 let qualname
= String
::new();
217 let scope
= data
.scope
.to_string();
218 let values
= make_values_str(&[
220 ("refidcrate", &ref_crate
),
221 ("qualname", &qualname
),
225 self.record("fn_call", data
.span
, values
);
228 fn method(&mut self, span
: Span
, data
: MethodData
) {
230 self.dump_span("method_decl", span
);
234 let id
= data
.id
.to_string();
235 let scope
= data
.scope
.to_string();
236 let values
= make_values_str(&[
238 ("qualname", &data
.qualname
),
242 self.record("method_decl", span
, values
);
245 fn method_call(&mut self, span
: Span
, data
: MethodCallData
) {
247 self.dump_span("method_call", span
);
251 let (dcn
, dck
) = match data
.decl_id
{
252 Some(declid
) => (declid
.index
.as_usize().to_string(), declid
.krate
.to_string()),
253 None
=> (String
::new(), String
::new()),
256 let ref_id
= data
.ref_id
.unwrap_or(null_def_id());
258 let def_id
= ref_id
.index
.as_usize().to_string();
259 let def_crate
= ref_id
.krate
.to_string();
260 let scope
= data
.scope
.to_string();
261 let values
= make_values_str(&[
263 ("refidcrate", &def_crate
),
265 ("declidcrate", &dck
),
269 self.record("method_call", data
.span
, values
);
272 fn macro_data(&mut self, span
: Span
, data
: MacroData
) {
274 self.dump_span("macro", span
);
278 let values
= make_values_str(&[
279 ("name", &data
.name
),
280 ("qualname", &data
.qualname
)
283 self.record("macro", data
.span
, values
);
286 fn macro_use(&mut self, span
: Span
, data
: MacroUseData
) {
288 self.dump_span("macro_use", span
);
292 let scope
= data
.scope
.to_string();
293 let values
= make_values_str(&[
294 ("callee_name", &data
.name
),
295 ("qualname", &data
.qualname
),
299 self.record("macro_use", data
.span
, values
);
302 fn mod_data(&mut self, data
: ModData
) {
307 let id
= data
.id
.to_string();
308 let scope
= data
.scope
.to_string();
309 let values
= make_values_str(&[
311 ("qualname", &data
.qualname
),
313 ("def_file", &data
.filename
)
316 self.record("module", data
.span
, values
);
319 fn mod_ref(&mut self, span
: Span
, data
: ModRefData
) {
321 self.dump_span("mod_ref", span
);
325 let (ref_id
, ref_crate
) = match data
.ref_id
{
326 Some(rid
) => (rid
.index
.as_usize().to_string(), rid
.krate
.to_string()),
327 None
=> (0.to_string(), 0.to_string())
330 let scope
= data
.scope
.to_string();
331 let values
= make_values_str(&[
333 ("refidcrate", &ref_crate
),
334 ("qualname", &data
.qualname
),
338 self.record("mod_ref", data
.span
, values
);
341 fn struct_data(&mut self, span
: Span
, data
: StructData
) {
343 self.dump_span("struct", span
);
347 let id
= data
.id
.to_string();
348 let ctor_id
= data
.ctor_id
.to_string();
349 let scope
= data
.scope
.to_string();
350 let values
= make_values_str(&[
352 ("ctor_id", &ctor_id
),
353 ("qualname", &data
.qualname
),
355 ("value", &data
.value
)
358 self.record("struct", data
.span
, values
);
361 fn struct_variant(&mut self, span
: Span
, data
: StructVariantData
) {
363 self.dump_span("variant_struct", span
);
367 let id
= data
.id
.to_string();
368 let scope
= data
.scope
.to_string();
369 let values
= make_values_str(&[
372 ("qualname", &data
.qualname
),
373 ("type", &data
.type_value
),
374 ("value", &data
.value
),
378 self.record("variant_struct", data
.span
, values
);
381 fn trait_data(&mut self, span
: Span
, data
: TraitData
) {
383 self.dump_span("trait", span
);
387 let id
= data
.id
.to_string();
388 let scope
= data
.scope
.to_string();
389 let values
= make_values_str(&[
391 ("qualname", &data
.qualname
),
393 ("value", &data
.value
)
396 self.record("trait", data
.span
, values
);
399 fn tuple_variant(&mut self, span
: Span
, data
: TupleVariantData
) {
401 self.dump_span("variant", span
);
405 let id
= data
.id
.to_string();
406 let scope
= data
.scope
.to_string();
407 let values
= make_values_str(&[
409 ("name", &data
.name
),
410 ("qualname", &data
.qualname
),
411 ("type", &data
.type_value
),
412 ("value", &data
.value
),
416 self.record("variant", data
.span
, values
);
419 fn type_ref(&mut self, span
: Span
, data
: TypeRefData
) {
421 self.dump_span("type_ref", span
);
425 let (ref_id
, ref_crate
) = match data
.ref_id
{
426 Some(id
) => (id
.index
.as_usize().to_string(), id
.krate
.to_string()),
427 None
=> (0.to_string(), 0.to_string())
430 let scope
= data
.scope
.to_string();
431 let values
= make_values_str(&[
433 ("refidcrate", &ref_crate
),
434 ("qualname", &data
.qualname
),
438 self.record("type_ref", data
.span
, values
);
441 fn typedef(&mut self, span
: Span
, data
: TypedefData
) {
443 self.dump_span("typedef", span
);
447 let id
= data
.id
.to_string();
448 let values
= make_values_str(&[
450 ("qualname", &data
.qualname
),
451 ("value", &data
.value
)
454 self.record("typedef", data
.span
, values
);
457 fn use_data(&mut self, span
: Span
, data
: UseData
) {
459 self.dump_span("use_alias", span
);
463 let mod_id
= data
.mod_id
.unwrap_or(null_def_id());
465 let id
= data
.id
.to_string();
466 let ref_id
= mod_id
.index
.as_usize().to_string();
467 let ref_crate
= mod_id
.krate
.to_string();
468 let scope
= data
.scope
.to_string();
469 let values
= make_values_str(&[
472 ("refidcrate", &ref_crate
),
473 ("name", &data
.name
),
477 self.record("use_alias", data
.span
, values
);
480 fn use_glob(&mut self, span
: Span
, data
: UseGlobData
) {
482 self.dump_span("use_glob", span
);
486 let names
= data
.names
.join(", ");
488 let id
= data
.id
.to_string();
489 let scope
= data
.scope
.to_string();
490 let values
= make_values_str(&[
496 self.record("use_glob", data
.span
, values
);
499 fn variable(&mut self, span
: Span
, data
: VariableData
) {
501 self.dump_span("variable", span
);
505 let id
= data
.id
.to_string();
506 let scope
= data
.scope
.to_string();
507 let values
= make_values_str(&[
509 ("name", &data
.name
),
510 ("qualname", &data
.qualname
),
511 ("value", &data
.value
),
512 ("type", &data
.type_value
),
516 self.record("variable", data
.span
, values
);
519 fn variable_ref(&mut self, span
: Span
, data
: VariableRefData
) {
521 self.dump_span("var_ref", span
);
525 let ref_id
= data
.ref_id
.index
.as_usize().to_string();
526 let ref_crate
= data
.ref_id
.krate
.to_string();
527 let scope
= data
.scope
.to_string();
528 let values
= make_values_str(&[
530 ("refidcrate", &ref_crate
),
535 self.record("var_ref", data
.span
, values
)
539 // Helper function to escape quotes in a string
540 fn escape(s
: String
) -> String
{
541 s
.replace("\"", "\"\"")
544 fn make_values_str(pairs
: &[(&'
static str, &str)]) -> String
{
545 let pairs
= pairs
.into_iter().map(|&(f
, v
)| {
546 // Never take more than 1020 chars
554 let strs
= pairs
.map(|(f
, v
)| format
!(",{},\"{}\"", f
, escape(String
::from(v
))));
555 strs
.fold(String
::new(), |mut s
, ss
| {
561 fn null_def_id() -> DefId
{
564 index
: DefIndex
::new(0),