]>
Commit | Line | Data |
---|---|---|
54a0048b SL |
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. | |
4 | // | |
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. | |
10 | ||
11 | use std::io::Write; | |
12 | ||
a7813a04 | 13 | use super::external_data::*; |
54a0048b | 14 | use super::dump::Dump; |
54a0048b | 15 | |
a7813a04 XL |
16 | pub struct CsvDumper<'b, W: 'b> { |
17 | output: &'b mut W | |
54a0048b SL |
18 | } |
19 | ||
a7813a04 XL |
20 | impl<'b, W: Write> CsvDumper<'b, W> { |
21 | pub fn new(writer: &'b mut W) -> CsvDumper<'b, W> { | |
22 | CsvDumper { output: writer } | |
54a0048b SL |
23 | } |
24 | ||
a7813a04 XL |
25 | fn record(&mut self, kind: &str, span: SpanData, values: String) { |
26 | let span_str = span_extent_str(span); | |
54a0048b SL |
27 | if let Err(_) = write!(self.output, "{},{}{}\n", kind, span_str, values) { |
28 | error!("Error writing output"); | |
29 | } | |
30 | } | |
31 | ||
32 | fn record_raw(&mut self, info: &str) { | |
33 | if let Err(_) = write!(self.output, "{}", info) { | |
34 | error!("Error writing output '{}'", info); | |
35 | } | |
36 | } | |
54a0048b SL |
37 | } |
38 | ||
a7813a04 XL |
39 | impl<'b, W: Write + 'b> Dump for CsvDumper<'b, W> { |
40 | fn crate_prelude(&mut self, data: CratePreludeData) { | |
54a0048b SL |
41 | let values = make_values_str(&[ |
42 | ("name", &data.crate_name), | |
a7813a04 | 43 | ("crate_root", &data.crate_root) |
54a0048b SL |
44 | ]); |
45 | ||
a7813a04 | 46 | self.record("crate", data.span, values); |
54a0048b SL |
47 | |
48 | for c in data.external_crates { | |
49 | let num = c.num.to_string(); | |
54a0048b SL |
50 | let values = make_values_str(&[ |
51 | ("name", &c.name), | |
52 | ("crate", &num), | |
a7813a04 | 53 | ("file_name", &c.file_name) |
54a0048b SL |
54 | ]); |
55 | ||
56 | self.record_raw(&format!("external_crate{}\n", values)); | |
57 | } | |
58 | ||
59 | self.record_raw("end_external_crates\n"); | |
60 | } | |
61 | ||
a7813a04 XL |
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(); | |
54a0048b SL |
65 | let values = make_values_str(&[ |
66 | ("id", &id), | |
67 | ("qualname", &data.qualname), | |
68 | ("scopeid", &scope), | |
69 | ("value", &data.value) | |
70 | ]); | |
71 | ||
72 | self.record("enum", data.span, values); | |
73 | } | |
74 | ||
a7813a04 XL |
75 | fn extern_crate(&mut self, data: ExternCrateData) { |
76 | let id = data.id.index.as_u32().to_string(); | |
54a0048b | 77 | let crate_num = data.crate_num.to_string(); |
a7813a04 | 78 | let scope = data.scope.index.as_u32().to_string(); |
54a0048b SL |
79 | let values = make_values_str(&[ |
80 | ("id", &id), | |
81 | ("name", &data.name), | |
82 | ("location", &data.location), | |
83 | ("crate", &crate_num), | |
84 | ("scopeid", &scope) | |
85 | ]); | |
86 | ||
87 | self.record("extern_crate", data.span, values); | |
88 | } | |
89 | ||
a7813a04 | 90 | fn impl_data(&mut self, data: ImplData) { |
54a0048b SL |
91 | let self_ref = data.self_ref.unwrap_or(null_def_id()); |
92 | let trait_ref = data.trait_ref.unwrap_or(null_def_id()); | |
93 | ||
a7813a04 | 94 | let id = data.id.index.as_u32().to_string(); |
54a0048b SL |
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(); | |
a7813a04 | 99 | let scope = data.scope.index.as_u32().to_string(); |
54a0048b SL |
100 | let values = make_values_str(&[ |
101 | ("id", &id), | |
102 | ("refid", &ref_id), | |
103 | ("refidcrate", &ref_id_crate), | |
104 | ("traitid", &trait_id), | |
105 | ("traitidcrate", &trait_id_crate), | |
106 | ("scopeid", &scope) | |
107 | ]); | |
108 | ||
109 | self.record("impl", data.span, values); | |
110 | } | |
111 | ||
112 | fn inheritance(&mut self, data: InheritanceData) { | |
54a0048b SL |
113 | let base_id = data.base_id.index.as_usize().to_string(); |
114 | let base_crate = data.base_id.krate.to_string(); | |
a7813a04 XL |
115 | let deriv_id = data.deriv_id.index.as_u32().to_string(); |
116 | let deriv_crate = data.deriv_id.krate.to_string(); | |
54a0048b SL |
117 | let values = make_values_str(&[ |
118 | ("base", &base_id), | |
119 | ("basecrate", &base_crate), | |
120 | ("derived", &deriv_id), | |
121 | ("derivedcrate", &deriv_crate) | |
122 | ]); | |
123 | ||
124 | self.record("inheritance", data.span, values); | |
125 | } | |
126 | ||
a7813a04 | 127 | fn function(&mut self, data: FunctionData) { |
54a0048b SL |
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()) | |
131 | }; | |
132 | ||
a7813a04 XL |
133 | let id = data.id.index.as_u32().to_string(); |
134 | let scope = data.scope.index.as_u32().to_string(); | |
54a0048b SL |
135 | let values = make_values_str(&[ |
136 | ("id", &id), | |
137 | ("qualname", &data.qualname), | |
138 | ("declid", &decl_id), | |
139 | ("declidcrate", &decl_crate), | |
140 | ("scopeid", &scope) | |
141 | ]); | |
142 | ||
143 | self.record("function", data.span, values); | |
144 | } | |
145 | ||
a7813a04 | 146 | fn function_ref(&mut self, data: FunctionRefData) { |
54a0048b SL |
147 | let ref_id = data.ref_id.index.as_usize().to_string(); |
148 | let ref_crate = data.ref_id.krate.to_string(); | |
a7813a04 | 149 | let scope = data.scope.index.as_u32().to_string(); |
54a0048b SL |
150 | let values = make_values_str(&[ |
151 | ("refid", &ref_id), | |
152 | ("refidcrate", &ref_crate), | |
153 | ("qualname", ""), | |
154 | ("scopeid", &scope) | |
155 | ]); | |
156 | ||
157 | self.record("fn_ref", data.span, values); | |
158 | } | |
159 | ||
a7813a04 | 160 | fn function_call(&mut self, data: FunctionCallData) { |
54a0048b SL |
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(); | |
a7813a04 | 164 | let scope = data.scope.index.as_u32().to_string(); |
54a0048b SL |
165 | let values = make_values_str(&[ |
166 | ("refid", &ref_id), | |
167 | ("refidcrate", &ref_crate), | |
168 | ("qualname", &qualname), | |
169 | ("scopeid", &scope) | |
170 | ]); | |
171 | ||
172 | self.record("fn_call", data.span, values); | |
173 | } | |
174 | ||
a7813a04 XL |
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(); | |
54a0048b SL |
178 | let values = make_values_str(&[ |
179 | ("id", &id), | |
180 | ("qualname", &data.qualname), | |
181 | ("scopeid", &scope) | |
182 | ]); | |
183 | ||
a7813a04 | 184 | self.record("method_decl", data.span, values); |
54a0048b SL |
185 | } |
186 | ||
a7813a04 | 187 | fn method_call(&mut self, data: MethodCallData) { |
54a0048b SL |
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()), | |
191 | }; | |
192 | ||
193 | let ref_id = data.ref_id.unwrap_or(null_def_id()); | |
194 | ||
195 | let def_id = ref_id.index.as_usize().to_string(); | |
196 | let def_crate = ref_id.krate.to_string(); | |
a7813a04 | 197 | let scope = data.scope.index.as_u32().to_string(); |
54a0048b SL |
198 | let values = make_values_str(&[ |
199 | ("refid", &def_id), | |
200 | ("refidcrate", &def_crate), | |
201 | ("declid", &dcn), | |
202 | ("declidcrate", &dck), | |
203 | ("scopeid", &scope) | |
204 | ]); | |
205 | ||
206 | self.record("method_call", data.span, values); | |
207 | } | |
208 | ||
a7813a04 | 209 | fn macro_data(&mut self, data: MacroData) { |
54a0048b SL |
210 | let values = make_values_str(&[ |
211 | ("name", &data.name), | |
212 | ("qualname", &data.qualname) | |
213 | ]); | |
214 | ||
215 | self.record("macro", data.span, values); | |
216 | } | |
217 | ||
a7813a04 XL |
218 | fn macro_use(&mut self, data: MacroUseData) { |
219 | let scope = data.scope.index.as_u32().to_string(); | |
54a0048b SL |
220 | let values = make_values_str(&[ |
221 | ("callee_name", &data.name), | |
222 | ("qualname", &data.qualname), | |
223 | ("scopeid", &scope) | |
224 | ]); | |
225 | ||
226 | self.record("macro_use", data.span, values); | |
227 | } | |
228 | ||
229 | fn mod_data(&mut self, data: ModData) { | |
a7813a04 XL |
230 | let id = data.id.index.as_u32().to_string(); |
231 | let scope = data.scope.index.as_u32().to_string(); | |
54a0048b SL |
232 | let values = make_values_str(&[ |
233 | ("id", &id), | |
234 | ("qualname", &data.qualname), | |
235 | ("scopeid", &scope), | |
236 | ("def_file", &data.filename) | |
237 | ]); | |
238 | ||
239 | self.record("module", data.span, values); | |
240 | } | |
241 | ||
a7813a04 | 242 | fn mod_ref(&mut self, data: ModRefData) { |
54a0048b SL |
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()) | |
246 | }; | |
247 | ||
a7813a04 | 248 | let scope = data.scope.index.as_u32().to_string(); |
54a0048b SL |
249 | let values = make_values_str(&[ |
250 | ("refid", &ref_id), | |
251 | ("refidcrate", &ref_crate), | |
252 | ("qualname", &data.qualname), | |
253 | ("scopeid", &scope) | |
254 | ]); | |
255 | ||
256 | self.record("mod_ref", data.span, values); | |
257 | } | |
258 | ||
a7813a04 XL |
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(); | |
54a0048b SL |
263 | let values = make_values_str(&[ |
264 | ("id", &id), | |
265 | ("ctor_id", &ctor_id), | |
266 | ("qualname", &data.qualname), | |
267 | ("scopeid", &scope), | |
268 | ("value", &data.value) | |
269 | ]); | |
270 | ||
271 | self.record("struct", data.span, values); | |
272 | } | |
273 | ||
a7813a04 XL |
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(); | |
54a0048b SL |
277 | let values = make_values_str(&[ |
278 | ("id", &id), | |
279 | ("ctor_id", &id), | |
280 | ("qualname", &data.qualname), | |
281 | ("type", &data.type_value), | |
282 | ("value", &data.value), | |
283 | ("scopeid", &scope) | |
284 | ]); | |
285 | ||
286 | self.record("variant_struct", data.span, values); | |
287 | } | |
288 | ||
a7813a04 XL |
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(); | |
54a0048b SL |
292 | let values = make_values_str(&[ |
293 | ("id", &id), | |
294 | ("qualname", &data.qualname), | |
295 | ("scopeid", &scope), | |
296 | ("value", &data.value) | |
297 | ]); | |
298 | ||
299 | self.record("trait", data.span, values); | |
300 | } | |
301 | ||
a7813a04 XL |
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(); | |
54a0048b SL |
305 | let values = make_values_str(&[ |
306 | ("id", &id), | |
307 | ("name", &data.name), | |
308 | ("qualname", &data.qualname), | |
309 | ("type", &data.type_value), | |
310 | ("value", &data.value), | |
311 | ("scopeid", &scope) | |
312 | ]); | |
313 | ||
314 | self.record("variant", data.span, values); | |
315 | } | |
316 | ||
a7813a04 | 317 | fn type_ref(&mut self, data: TypeRefData) { |
54a0048b SL |
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()) | |
321 | }; | |
322 | ||
a7813a04 | 323 | let scope = data.scope.index.as_u32().to_string(); |
54a0048b SL |
324 | let values = make_values_str(&[ |
325 | ("refid", &ref_id), | |
326 | ("refidcrate", &ref_crate), | |
327 | ("qualname", &data.qualname), | |
328 | ("scopeid", &scope) | |
329 | ]); | |
330 | ||
331 | self.record("type_ref", data.span, values); | |
332 | } | |
333 | ||
a7813a04 XL |
334 | fn typedef(&mut self, data: TypeDefData) { |
335 | let id = data.id.index.as_u32().to_string(); | |
54a0048b SL |
336 | let values = make_values_str(&[ |
337 | ("id", &id), | |
338 | ("qualname", &data.qualname), | |
339 | ("value", &data.value) | |
340 | ]); | |
341 | ||
342 | self.record("typedef", data.span, values); | |
343 | } | |
344 | ||
a7813a04 | 345 | fn use_data(&mut self, data: UseData) { |
54a0048b SL |
346 | let mod_id = data.mod_id.unwrap_or(null_def_id()); |
347 | ||
a7813a04 | 348 | let id = data.id.index.as_u32().to_string(); |
54a0048b SL |
349 | let ref_id = mod_id.index.as_usize().to_string(); |
350 | let ref_crate = mod_id.krate.to_string(); | |
a7813a04 | 351 | let scope = data.scope.index.as_u32().to_string(); |
54a0048b SL |
352 | let values = make_values_str(&[ |
353 | ("id", &id), | |
354 | ("refid", &ref_id), | |
355 | ("refidcrate", &ref_crate), | |
356 | ("name", &data.name), | |
357 | ("scopeid", &scope) | |
358 | ]); | |
359 | ||
360 | self.record("use_alias", data.span, values); | |
361 | } | |
362 | ||
a7813a04 | 363 | fn use_glob(&mut self, data: UseGlobData) { |
54a0048b SL |
364 | let names = data.names.join(", "); |
365 | ||
a7813a04 XL |
366 | let id = data.id.index.as_u32().to_string(); |
367 | let scope = data.scope.index.as_u32().to_string(); | |
54a0048b SL |
368 | let values = make_values_str(&[ |
369 | ("id", &id), | |
370 | ("value", &names), | |
371 | ("scopeid", &scope) | |
372 | ]); | |
373 | ||
374 | self.record("use_glob", data.span, values); | |
375 | } | |
376 | ||
a7813a04 XL |
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(); | |
54a0048b SL |
380 | let values = make_values_str(&[ |
381 | ("id", &id), | |
382 | ("name", &data.name), | |
383 | ("qualname", &data.qualname), | |
384 | ("value", &data.value), | |
385 | ("type", &data.type_value), | |
386 | ("scopeid", &scope) | |
387 | ]); | |
388 | ||
389 | self.record("variable", data.span, values); | |
390 | } | |
391 | ||
a7813a04 | 392 | fn variable_ref(&mut self, data: VariableRefData) { |
54a0048b SL |
393 | let ref_id = data.ref_id.index.as_usize().to_string(); |
394 | let ref_crate = data.ref_id.krate.to_string(); | |
a7813a04 | 395 | let scope = data.scope.index.as_u32().to_string(); |
54a0048b SL |
396 | let values = make_values_str(&[ |
397 | ("refid", &ref_id), | |
398 | ("refidcrate", &ref_crate), | |
399 | ("qualname", ""), | |
400 | ("scopeid", &scope) | |
401 | ]); | |
402 | ||
403 | self.record("var_ref", data.span, values) | |
404 | } | |
405 | } | |
406 | ||
407 | // Helper function to escape quotes in a string | |
408 | fn escape(s: String) -> String { | |
409 | s.replace("\"", "\"\"") | |
410 | } | |
411 | ||
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 | |
415 | if v.len() > 1020 { | |
416 | (f, &v[..1020]) | |
417 | } else { | |
418 | (f, v) | |
419 | } | |
420 | }); | |
421 | ||
422 | let strs = pairs.map(|(f, v)| format!(",{},\"{}\"", f, escape(String::from(v)))); | |
423 | strs.fold(String::new(), |mut s, ss| { | |
424 | s.push_str(&ss[..]); | |
425 | s | |
426 | }) | |
427 | } | |
428 | ||
a7813a04 | 429 | fn span_extent_str(span: SpanData) -> String { |
5bcae85e | 430 | format!("file_name,\"{}\",file_line,{},file_col,{},byte_start,{},\ |
a7813a04 XL |
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) | |
54a0048b | 434 | } |