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 super::external_data::*;
14 use super::dump::Dump;
16 pub struct CsvDumper<'b, W: 'b> {
20 impl<'b, W: Write> CsvDumper<'b, W> {
21 pub fn new(writer: &'b mut W) -> CsvDumper<'b, W> {
22 CsvDumper { output: writer }
25 fn record(&mut self, kind: &str, span: SpanData, values: String) {
26 let span_str = span_extent_str(span);
27 if let Err(_) = write!(self.output, "{},{}{}\n", kind, span_str, values) {
28 error!("Error writing output");
32 fn record_raw(&mut self, info: &str) {
33 if let Err(_) = write!(self.output, "{}", info) {
34 error!("Error writing output '{}'", info);
39 impl<'b, W: Write + 'b> Dump for CsvDumper<'b, W> {
40 fn crate_prelude(&mut self, data: CratePreludeData) {
41 let values = make_values_str(&[
42 ("name", &data.crate_name),
43 ("crate_root", &data.crate_root)
46 self.record("crate", data.span, values);
48 for c in data.external_crates {
49 let num = c.num.to_string();
50 let values = make_values_str(&[
53 ("file_name", &c.file_name)
56 self.record_raw(&format!("external_crate{}\n", values));
59 self.record_raw("end_external_crates\n");
62 fn enum_data(&mut self, data: EnumData) {
63 let id = data.id.index.as_u32().to_string();
64 let scope = data.scope.index.as_u32().to_string();
65 let values = make_values_str(&[
67 ("qualname", &data.qualname),
69 ("value", &data.value)
72 self.record("enum", data.span, values);
75 fn extern_crate(&mut self, data: ExternCrateData) {
76 let id = data.id.index.as_u32().to_string();
77 let crate_num = data.crate_num.to_string();
78 let scope = data.scope.index.as_u32().to_string();
79 let values = make_values_str(&[
82 ("location", &data.location),
83 ("crate", &crate_num),
87 self.record("extern_crate", data.span, values);
90 fn impl_data(&mut self, data: ImplData) {
91 let self_ref = data.self_ref.unwrap_or(null_def_id());
92 let trait_ref = data.trait_ref.unwrap_or(null_def_id());
94 let id = data.id.index.as_u32().to_string();
95 let ref_id = self_ref.index.as_usize().to_string();
96 let ref_id_crate = self_ref.krate.to_string();
97 let trait_id = trait_ref.index.as_usize().to_string();
98 let trait_id_crate = trait_ref.krate.to_string();
99 let scope = data.scope.index.as_u32().to_string();
100 let values = make_values_str(&[
103 ("refidcrate", &ref_id_crate),
104 ("traitid", &trait_id),
105 ("traitidcrate", &trait_id_crate),
109 self.record("impl", data.span, values);
112 fn inheritance(&mut self, data: InheritanceData) {
113 let base_id = data.base_id.index.as_usize().to_string();
114 let base_crate = data.base_id.krate.to_string();
115 let deriv_id = data.deriv_id.index.as_u32().to_string();
116 let deriv_crate = data.deriv_id.krate.to_string();
117 let values = make_values_str(&[
119 ("basecrate", &base_crate),
120 ("derived", &deriv_id),
121 ("derivedcrate", &deriv_crate)
124 self.record("inheritance", data.span, values);
127 fn function(&mut self, data: FunctionData) {
128 let (decl_id, decl_crate) = match data.declaration {
129 Some(id) => (id.index.as_usize().to_string(), id.krate.to_string()),
130 None => (String::new(), String::new())
133 let id = data.id.index.as_u32().to_string();
134 let scope = data.scope.index.as_u32().to_string();
135 let values = make_values_str(&[
137 ("qualname", &data.qualname),
138 ("declid", &decl_id),
139 ("declidcrate", &decl_crate),
143 self.record("function", data.span, values);
146 fn function_ref(&mut self, data: FunctionRefData) {
147 let ref_id = data.ref_id.index.as_usize().to_string();
148 let ref_crate = data.ref_id.krate.to_string();
149 let scope = data.scope.index.as_u32().to_string();
150 let values = make_values_str(&[
152 ("refidcrate", &ref_crate),
157 self.record("fn_ref", data.span, values);
160 fn function_call(&mut self, data: FunctionCallData) {
161 let ref_id = data.ref_id.index.as_usize().to_string();
162 let ref_crate = data.ref_id.krate.to_string();
163 let qualname = String::new();
164 let scope = data.scope.index.as_u32().to_string();
165 let values = make_values_str(&[
167 ("refidcrate", &ref_crate),
168 ("qualname", &qualname),
172 self.record("fn_call", data.span, values);
175 fn method(&mut self, data: MethodData) {
176 let id = data.id.index.as_u32().to_string();
177 let scope = data.scope.index.as_u32().to_string();
178 let values = make_values_str(&[
180 ("qualname", &data.qualname),
184 self.record("method_decl", data.span, values);
187 fn method_call(&mut self, data: MethodCallData) {
188 let (dcn, dck) = match data.decl_id {
189 Some(declid) => (declid.index.as_usize().to_string(), declid.krate.to_string()),
190 None => (String::new(), String::new()),
193 let ref_id = data.ref_id.unwrap_or(null_def_id());
195 let def_id = ref_id.index.as_usize().to_string();
196 let def_crate = ref_id.krate.to_string();
197 let scope = data.scope.index.as_u32().to_string();
198 let values = make_values_str(&[
200 ("refidcrate", &def_crate),
202 ("declidcrate", &dck),
206 self.record("method_call", data.span, values);
209 fn macro_data(&mut self, data: MacroData) {
210 let values = make_values_str(&[
211 ("name", &data.name),
212 ("qualname", &data.qualname)
215 self.record("macro", data.span, values);
218 fn macro_use(&mut self, data: MacroUseData) {
219 let scope = data.scope.index.as_u32().to_string();
220 let values = make_values_str(&[
221 ("callee_name", &data.name),
222 ("qualname", &data.qualname),
226 self.record("macro_use", data.span, values);
229 fn mod_data(&mut self, data: ModData) {
230 let id = data.id.index.as_u32().to_string();
231 let scope = data.scope.index.as_u32().to_string();
232 let values = make_values_str(&[
234 ("qualname", &data.qualname),
236 ("def_file", &data.filename)
239 self.record("module", data.span, values);
242 fn mod_ref(&mut self, data: ModRefData) {
243 let (ref_id, ref_crate) = match data.ref_id {
244 Some(rid) => (rid.index.as_usize().to_string(), rid.krate.to_string()),
245 None => (0.to_string(), 0.to_string())
248 let scope = data.scope.index.as_u32().to_string();
249 let values = make_values_str(&[
251 ("refidcrate", &ref_crate),
252 ("qualname", &data.qualname),
256 self.record("mod_ref", data.span, values);
259 fn struct_data(&mut self, data: StructData) {
260 let id = data.id.index.as_u32().to_string();
261 let ctor_id = data.ctor_id.index.as_u32().to_string();
262 let scope = data.scope.index.as_u32().to_string();
263 let values = make_values_str(&[
265 ("ctor_id", &ctor_id),
266 ("qualname", &data.qualname),
268 ("value", &data.value)
271 self.record("struct", data.span, values);
274 fn struct_variant(&mut self, data: StructVariantData) {
275 let id = data.id.index.as_u32().to_string();
276 let scope = data.scope.index.as_u32().to_string();
277 let values = make_values_str(&[
280 ("qualname", &data.qualname),
281 ("type", &data.type_value),
282 ("value", &data.value),
286 self.record("variant_struct", data.span, values);
289 fn trait_data(&mut self, data: TraitData) {
290 let id = data.id.index.as_u32().to_string();
291 let scope = data.scope.index.as_u32().to_string();
292 let values = make_values_str(&[
294 ("qualname", &data.qualname),
296 ("value", &data.value)
299 self.record("trait", data.span, values);
302 fn tuple_variant(&mut self, data: TupleVariantData) {
303 let id = data.id.index.as_u32().to_string();
304 let scope = data.scope.index.as_u32().to_string();
305 let values = make_values_str(&[
307 ("name", &data.name),
308 ("qualname", &data.qualname),
309 ("type", &data.type_value),
310 ("value", &data.value),
314 self.record("variant", data.span, values);
317 fn type_ref(&mut self, data: TypeRefData) {
318 let (ref_id, ref_crate) = match data.ref_id {
319 Some(id) => (id.index.as_usize().to_string(), id.krate.to_string()),
320 None => (0.to_string(), 0.to_string())
323 let scope = data.scope.index.as_u32().to_string();
324 let values = make_values_str(&[
326 ("refidcrate", &ref_crate),
327 ("qualname", &data.qualname),
331 self.record("type_ref", data.span, values);
334 fn typedef(&mut self, data: TypeDefData) {
335 let id = data.id.index.as_u32().to_string();
336 let values = make_values_str(&[
338 ("qualname", &data.qualname),
339 ("value", &data.value)
342 self.record("typedef", data.span, values);
345 fn use_data(&mut self, data: UseData) {
346 let mod_id = data.mod_id.unwrap_or(null_def_id());
348 let id = data.id.index.as_u32().to_string();
349 let ref_id = mod_id.index.as_usize().to_string();
350 let ref_crate = mod_id.krate.to_string();
351 let scope = data.scope.index.as_u32().to_string();
352 let values = make_values_str(&[
355 ("refidcrate", &ref_crate),
356 ("name", &data.name),
360 self.record("use_alias", data.span, values);
363 fn use_glob(&mut self, data: UseGlobData) {
364 let names = data.names.join(", ");
366 let id = data.id.index.as_u32().to_string();
367 let scope = data.scope.index.as_u32().to_string();
368 let values = make_values_str(&[
374 self.record("use_glob", data.span, values);
377 fn variable(&mut self, data: VariableData) {
378 let id = data.id.index.as_u32().to_string();
379 let scope = data.scope.index.as_u32().to_string();
380 let values = make_values_str(&[
382 ("name", &data.name),
383 ("qualname", &data.qualname),
384 ("value", &data.value),
385 ("type", &data.type_value),
389 self.record("variable", data.span, values);
392 fn variable_ref(&mut self, data: VariableRefData) {
393 let ref_id = data.ref_id.index.as_usize().to_string();
394 let ref_crate = data.ref_id.krate.to_string();
395 let scope = data.scope.index.as_u32().to_string();
396 let values = make_values_str(&[
398 ("refidcrate", &ref_crate),
403 self.record("var_ref", data.span, values)
407 // Helper function to escape quotes in a string
408 fn escape(s: String) -> String {
409 s.replace("\"", "\"\"")
412 fn make_values_str(pairs: &[(&'static str, &str)]) -> String {
413 let pairs = pairs.into_iter().map(|&(f, v)| {
414 // Never take more than 1020 chars
422 let strs = pairs.map(|(f, v)| format!(",{},\"{}\"", f, escape(String::from(v))));
423 strs.fold(String::new(), |mut s, ss| {
429 fn span_extent_str(span: SpanData) -> String {
430 format!("file_name,\"{}\",file_line,{},file_col,{},byte_start,{},\
431 file_line_end,{},file_col_end,{},byte_end,{}",
432 span.file_name, span.line_start, span.column_start, span.byte_start,
433 span.line_end, span.column_end, span.byte_end)