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