]> git.lizzy.rs Git - rust.git/blob - src/librustc_save_analysis/external_data.rs
245a3bcc61795bf32be467652e67ce2696839f92
[rust.git] / src / librustc_save_analysis / external_data.rs
1 // Copyright 2016 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 rustc::hir::def_id::{CrateNum, DefId, DefIndex};
12 use rustc::hir::map::Map;
13 use rustc::ty::TyCtxt;
14 use syntax::ast::{self, NodeId};
15 use syntax::codemap::CodeMap;
16 use syntax::print::pprust;
17 use syntax_pos::Span;
18
19 use data::{self, Visibility};
20
21 use rls_data::{SpanData, CratePreludeData, Attribute, Signature};
22 use rls_span::{Column, Row};
23
24 // FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
25 pub trait Lower {
26     type Target;
27     fn lower(self, tcx: TyCtxt) -> Self::Target;
28 }
29
30 pub fn make_def_id(id: NodeId, map: &Map) -> DefId {
31     map.opt_local_def_id(id).unwrap_or(null_def_id())
32 }
33
34 pub fn null_def_id() -> DefId {
35     DefId {
36         krate: CrateNum::from_u32(u32::max_value()),
37         index: DefIndex::from_u32(u32::max_value())
38     }
39 }
40
41 pub fn span_from_span(span: Span, cm: &CodeMap) -> SpanData {
42     let start = cm.lookup_char_pos(span.lo);
43     let end = cm.lookup_char_pos(span.hi);
44
45     SpanData {
46         file_name: start.file.name.clone().into(),
47         byte_start: span.lo.0,
48         byte_end: span.hi.0,
49         line_start: Row::new_one_indexed(start.line as u32),
50         line_end: Row::new_one_indexed(end.line as u32),
51         column_start: Column::new_one_indexed(start.col.0 as u32 + 1),
52         column_end: Column::new_one_indexed(end.col.0 as u32 + 1),
53     }
54 }
55
56 impl Lower for Vec<ast::Attribute> {
57     type Target = Vec<Attribute>;
58
59     fn lower(self, tcx: TyCtxt) -> Vec<Attribute> {
60         self.into_iter()
61         // Only retain real attributes. Doc comments are lowered separately.
62         .filter(|attr| attr.path != "doc")
63         .map(|mut attr| {
64             // Remove the surrounding '#[..]' or '#![..]' of the pretty printed
65             // attribute. First normalize all inner attribute (#![..]) to outer
66             // ones (#[..]), then remove the two leading and the one trailing character.
67             attr.style = ast::AttrStyle::Outer;
68             let value = pprust::attribute_to_string(&attr);
69             // This str slicing works correctly, because the leading and trailing characters
70             // are in the ASCII range and thus exactly one byte each.
71             let value = value[2..value.len()-1].to_string();
72
73             Attribute {
74                 value: value,
75                 span: span_from_span(attr.span, tcx.sess.codemap()),
76             }
77         }).collect()
78     }
79 }
80
81 impl Lower for data::CratePreludeData {
82     type Target = CratePreludeData;
83
84     fn lower(self, tcx: TyCtxt) -> CratePreludeData {
85         CratePreludeData {
86             crate_name: self.crate_name,
87             crate_root: self.crate_root,
88             external_crates: self.external_crates,
89             span: span_from_span(self.span, tcx.sess.codemap()),
90         }
91     }
92 }
93
94 /// Data for enum declarations.
95 #[derive(Clone, Debug)]
96 pub struct EnumData {
97     pub id: DefId,
98     pub value: String,
99     pub name: String,
100     pub qualname: String,
101     pub span: SpanData,
102     pub scope: DefId,
103     pub variants: Vec<DefId>,
104     pub visibility: Visibility,
105     pub docs: String,
106     pub sig: Option<Signature>,
107     pub attributes: Vec<Attribute>,
108 }
109
110 impl Lower for data::EnumData {
111     type Target = EnumData;
112
113     fn lower(self, tcx: TyCtxt) -> EnumData {
114         EnumData {
115             id: make_def_id(self.id, &tcx.hir),
116             name: self.name,
117             value: self.value,
118             qualname: self.qualname,
119             span: span_from_span(self.span, tcx.sess.codemap()),
120             scope: make_def_id(self.scope, &tcx.hir),
121             variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
122             visibility: self.visibility,
123             docs: self.docs,
124             sig: self.sig,
125             attributes: self.attributes.lower(tcx),
126         }
127     }
128 }
129
130 /// Data for extern crates.
131 #[derive(Debug)]
132 pub struct ExternCrateData {
133     pub id: DefId,
134     pub name: String,
135     pub crate_num: CrateNum,
136     pub location: String,
137     pub span: SpanData,
138     pub scope: DefId,
139 }
140
141 impl Lower for data::ExternCrateData {
142     type Target = ExternCrateData;
143
144     fn lower(self, tcx: TyCtxt) -> ExternCrateData {
145         ExternCrateData {
146             id: make_def_id(self.id, &tcx.hir),
147             name: self.name,
148             crate_num: self.crate_num,
149             location: self.location,
150             span: span_from_span(self.span, tcx.sess.codemap()),
151             scope: make_def_id(self.scope, &tcx.hir),
152         }
153     }
154 }
155
156 /// Data about a function call.
157 #[derive(Debug)]
158 pub struct FunctionCallData {
159     pub span: SpanData,
160     pub scope: DefId,
161     pub ref_id: DefId,
162 }
163
164 impl Lower for data::FunctionCallData {
165     type Target = FunctionCallData;
166
167     fn lower(self, tcx: TyCtxt) -> FunctionCallData {
168         FunctionCallData {
169             span: span_from_span(self.span, tcx.sess.codemap()),
170             scope: make_def_id(self.scope, &tcx.hir),
171             ref_id: self.ref_id,
172         }
173     }
174 }
175
176 /// Data for all kinds of functions and methods.
177 #[derive(Clone, Debug)]
178 pub struct FunctionData {
179     pub id: DefId,
180     pub name: String,
181     pub qualname: String,
182     pub declaration: Option<DefId>,
183     pub span: SpanData,
184     pub scope: DefId,
185     pub value: String,
186     pub visibility: Visibility,
187     pub parent: Option<DefId>,
188     pub docs: String,
189     pub sig: Option<Signature>,
190     pub attributes: Vec<Attribute>,
191 }
192
193 impl Lower for data::FunctionData {
194     type Target = FunctionData;
195
196     fn lower(self, tcx: TyCtxt) -> FunctionData {
197         FunctionData {
198             id: make_def_id(self.id, &tcx.hir),
199             name: self.name,
200             qualname: self.qualname,
201             declaration: self.declaration,
202             span: span_from_span(self.span, tcx.sess.codemap()),
203             scope: make_def_id(self.scope, &tcx.hir),
204             value: self.value,
205             visibility: self.visibility,
206             parent: self.parent,
207             docs: self.docs,
208             sig: self.sig,
209             attributes: self.attributes.lower(tcx),
210         }
211     }
212 }
213
214 /// Data about a function call.
215 #[derive(Debug)]
216 pub struct FunctionRefData {
217     pub span: SpanData,
218     pub scope: DefId,
219     pub ref_id: DefId,
220 }
221
222 impl Lower for data::FunctionRefData {
223     type Target = FunctionRefData;
224
225     fn lower(self, tcx: TyCtxt) -> FunctionRefData {
226         FunctionRefData {
227             span: span_from_span(self.span, tcx.sess.codemap()),
228             scope: make_def_id(self.scope, &tcx.hir),
229             ref_id: self.ref_id,
230         }
231     }
232 }
233 #[derive(Debug)]
234 pub struct ImplData {
235     pub id: DefId,
236     pub span: SpanData,
237     pub scope: DefId,
238     pub trait_ref: Option<DefId>,
239     pub self_ref: Option<DefId>,
240 }
241
242 impl Lower for data::ImplData {
243     type Target = ImplData;
244
245     fn lower(self, tcx: TyCtxt) -> ImplData {
246         ImplData {
247             id: make_def_id(self.id, &tcx.hir),
248             span: span_from_span(self.span, tcx.sess.codemap()),
249             scope: make_def_id(self.scope, &tcx.hir),
250             trait_ref: self.trait_ref,
251             self_ref: self.self_ref,
252         }
253     }
254 }
255
256 #[derive(Debug)]
257 pub struct InheritanceData {
258     pub span: SpanData,
259     pub base_id: DefId,
260     pub deriv_id: DefId
261 }
262
263 impl Lower for data::InheritanceData {
264     type Target = InheritanceData;
265
266     fn lower(self, tcx: TyCtxt) -> InheritanceData {
267         InheritanceData {
268             span: span_from_span(self.span, tcx.sess.codemap()),
269             base_id: self.base_id,
270             deriv_id: make_def_id(self.deriv_id, &tcx.hir)
271         }
272     }
273 }
274
275 /// Data about a macro declaration.
276 #[derive(Debug)]
277 pub struct MacroData {
278     pub span: SpanData,
279     pub name: String,
280     pub qualname: String,
281     pub docs: String,
282 }
283
284 impl Lower for data::MacroData {
285     type Target = MacroData;
286
287     fn lower(self, tcx: TyCtxt) -> MacroData {
288         MacroData {
289             span: span_from_span(self.span, tcx.sess.codemap()),
290             name: self.name,
291             qualname: self.qualname,
292             docs: self.docs,
293         }
294     }
295 }
296
297 /// Data about a macro use.
298 #[derive(Debug)]
299 pub struct MacroUseData {
300     pub span: SpanData,
301     pub name: String,
302     pub qualname: String,
303     // Because macro expansion happens before ref-ids are determined,
304     // we use the callee span to reference the associated macro definition.
305     pub callee_span: SpanData,
306     pub scope: DefId,
307 }
308
309 impl Lower for data::MacroUseData {
310     type Target = MacroUseData;
311
312     fn lower(self, tcx: TyCtxt) -> MacroUseData {
313         MacroUseData {
314             span: span_from_span(self.span, tcx.sess.codemap()),
315             name: self.name,
316             qualname: self.qualname,
317             callee_span: span_from_span(self.callee_span, tcx.sess.codemap()),
318             scope: make_def_id(self.scope, &tcx.hir),
319         }
320     }
321 }
322
323 /// Data about a method call.
324 #[derive(Debug)]
325 pub struct MethodCallData {
326     pub span: SpanData,
327     pub scope: DefId,
328     pub ref_id: Option<DefId>,
329     pub decl_id: Option<DefId>,
330 }
331
332 impl Lower for data::MethodCallData {
333     type Target = MethodCallData;
334
335     fn lower(self, tcx: TyCtxt) -> MethodCallData {
336         MethodCallData {
337             span: span_from_span(self.span, tcx.sess.codemap()),
338             scope: make_def_id(self.scope, &tcx.hir),
339             ref_id: self.ref_id,
340             decl_id: self.decl_id,
341         }
342     }
343 }
344
345 /// Data for method declarations (methods with a body are treated as functions).
346 #[derive(Clone, Debug)]
347 pub struct MethodData {
348     pub id: DefId,
349     pub name: String,
350     pub qualname: String,
351     pub span: SpanData,
352     pub scope: DefId,
353     pub value: String,
354     pub decl_id: Option<DefId>,
355     pub visibility: Visibility,
356     pub parent: Option<DefId>,
357     pub docs: String,
358     pub sig: Option<Signature>,
359     pub attributes: Vec<Attribute>,
360 }
361
362 impl Lower for data::MethodData {
363     type Target = MethodData;
364
365     fn lower(self, tcx: TyCtxt) -> MethodData {
366         MethodData {
367             span: span_from_span(self.span, tcx.sess.codemap()),
368             name: self.name,
369             scope: make_def_id(self.scope, &tcx.hir),
370             id: make_def_id(self.id, &tcx.hir),
371             qualname: self.qualname,
372             value: self.value,
373             decl_id: self.decl_id,
374             visibility: self.visibility,
375             parent: self.parent,
376             docs: self.docs,
377             sig: self.sig,
378             attributes: self.attributes.lower(tcx),
379         }
380     }
381 }
382
383 /// Data for modules.
384 #[derive(Debug)]
385 pub struct ModData {
386     pub id: DefId,
387     pub name: String,
388     pub qualname: String,
389     pub span: SpanData,
390     pub scope: DefId,
391     pub filename: String,
392     pub items: Vec<DefId>,
393     pub visibility: Visibility,
394     pub docs: String,
395     pub sig: Option<Signature>,
396     pub attributes: Vec<Attribute>,
397 }
398
399 impl Lower for data::ModData {
400     type Target = ModData;
401
402     fn lower(self, tcx: TyCtxt) -> ModData {
403         ModData {
404             id: make_def_id(self.id, &tcx.hir),
405             name: self.name,
406             qualname: self.qualname,
407             span: span_from_span(self.span, tcx.sess.codemap()),
408             scope: make_def_id(self.scope, &tcx.hir),
409             filename: self.filename,
410             items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
411             visibility: self.visibility,
412             docs: self.docs,
413             sig: self.sig,
414             attributes: self.attributes.lower(tcx),
415         }
416     }
417 }
418
419 /// Data for a reference to a module.
420 #[derive(Debug)]
421 pub struct ModRefData {
422     pub span: SpanData,
423     pub scope: DefId,
424     pub ref_id: Option<DefId>,
425     pub qualname: String
426 }
427
428 impl Lower for data::ModRefData {
429     type Target = ModRefData;
430
431     fn lower(self, tcx: TyCtxt) -> ModRefData {
432         ModRefData {
433             span: span_from_span(self.span, tcx.sess.codemap()),
434             scope: make_def_id(self.scope, &tcx.hir),
435             ref_id: self.ref_id,
436             qualname: self.qualname,
437         }
438     }
439 }
440
441 #[derive(Debug)]
442 pub struct StructData {
443     pub span: SpanData,
444     pub name: String,
445     pub id: DefId,
446     pub ctor_id: DefId,
447     pub qualname: String,
448     pub scope: DefId,
449     pub value: String,
450     pub fields: Vec<DefId>,
451     pub visibility: Visibility,
452     pub docs: String,
453     pub sig: Option<Signature>,
454     pub attributes: Vec<Attribute>,
455 }
456
457 impl Lower for data::StructData {
458     type Target = StructData;
459
460     fn lower(self, tcx: TyCtxt) -> StructData {
461         StructData {
462             span: span_from_span(self.span, tcx.sess.codemap()),
463             name: self.name,
464             id: make_def_id(self.id, &tcx.hir),
465             ctor_id: make_def_id(self.ctor_id, &tcx.hir),
466             qualname: self.qualname,
467             scope: make_def_id(self.scope, &tcx.hir),
468             value: self.value,
469             fields: self.fields.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
470             visibility: self.visibility,
471             docs: self.docs,
472             sig: self.sig,
473             attributes: self.attributes.lower(tcx),
474         }
475     }
476 }
477
478 #[derive(Debug)]
479 pub struct StructVariantData {
480     pub span: SpanData,
481     pub name: String,
482     pub id: DefId,
483     pub qualname: String,
484     pub type_value: String,
485     pub value: String,
486     pub scope: DefId,
487     pub parent: Option<DefId>,
488     pub docs: String,
489     pub sig: Option<Signature>,
490     pub attributes: Vec<Attribute>,
491 }
492
493 impl Lower for data::StructVariantData {
494     type Target = StructVariantData;
495
496     fn lower(self, tcx: TyCtxt) -> StructVariantData {
497         StructVariantData {
498             span: span_from_span(self.span, tcx.sess.codemap()),
499             name: self.name,
500             id: make_def_id(self.id, &tcx.hir),
501             qualname: self.qualname,
502             type_value: self.type_value,
503             value: self.value,
504             scope: make_def_id(self.scope, &tcx.hir),
505             parent: self.parent,
506             docs: self.docs,
507             sig: self.sig,
508             attributes: self.attributes.lower(tcx),
509         }
510     }
511 }
512
513 #[derive(Debug)]
514 pub struct TraitData {
515     pub span: SpanData,
516     pub name: String,
517     pub id: DefId,
518     pub qualname: String,
519     pub scope: DefId,
520     pub value: String,
521     pub items: Vec<DefId>,
522     pub visibility: Visibility,
523     pub docs: String,
524     pub sig: Option<Signature>,
525     pub attributes: Vec<Attribute>,
526 }
527
528 impl Lower for data::TraitData {
529     type Target = TraitData;
530
531     fn lower(self, tcx: TyCtxt) -> TraitData {
532         TraitData {
533             span: span_from_span(self.span, tcx.sess.codemap()),
534             name: self.name,
535             id: make_def_id(self.id, &tcx.hir),
536             qualname: self.qualname,
537             scope: make_def_id(self.scope, &tcx.hir),
538             value: self.value,
539             items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
540             visibility: self.visibility,
541             docs: self.docs,
542             sig: self.sig,
543             attributes: self.attributes.lower(tcx),
544         }
545     }
546 }
547
548 #[derive(Debug)]
549 pub struct TupleVariantData {
550     pub span: SpanData,
551     pub id: DefId,
552     pub name: String,
553     pub qualname: String,
554     pub type_value: String,
555     pub value: String,
556     pub scope: DefId,
557     pub parent: Option<DefId>,
558     pub docs: String,
559     pub sig: Option<Signature>,
560     pub attributes: Vec<Attribute>,
561 }
562
563 impl Lower for data::TupleVariantData {
564     type Target = TupleVariantData;
565
566     fn lower(self, tcx: TyCtxt) -> TupleVariantData {
567         TupleVariantData {
568             span: span_from_span(self.span, tcx.sess.codemap()),
569             id: make_def_id(self.id, &tcx.hir),
570             name: self.name,
571             qualname: self.qualname,
572             type_value: self.type_value,
573             value: self.value,
574             scope: make_def_id(self.scope, &tcx.hir),
575             parent: self.parent,
576             docs: self.docs,
577             sig: self.sig,
578             attributes: self.attributes.lower(tcx),
579         }
580     }
581 }
582
583 /// Data for a typedef.
584 #[derive(Debug)]
585 pub struct TypeDefData {
586     pub id: DefId,
587     pub name: String,
588     pub span: SpanData,
589     pub qualname: String,
590     pub value: String,
591     pub visibility: Visibility,
592     pub parent: Option<DefId>,
593     pub docs: String,
594     pub sig: Option<Signature>,
595     pub attributes: Vec<Attribute>,
596 }
597
598 impl Lower for data::TypeDefData {
599     type Target = TypeDefData;
600
601     fn lower(self, tcx: TyCtxt) -> TypeDefData {
602         TypeDefData {
603             id: make_def_id(self.id, &tcx.hir),
604             name: self.name,
605             span: span_from_span(self.span, tcx.sess.codemap()),
606             qualname: self.qualname,
607             value: self.value,
608             visibility: self.visibility,
609             parent: self.parent,
610             docs: self.docs,
611             sig: self.sig,
612             attributes: self.attributes.lower(tcx),
613         }
614     }
615 }
616
617 /// Data for a reference to a type or trait.
618 #[derive(Clone, Debug)]
619 pub struct TypeRefData {
620     pub span: SpanData,
621     pub scope: DefId,
622     pub ref_id: Option<DefId>,
623     pub qualname: String,
624 }
625
626 impl Lower for data::TypeRefData {
627     type Target = TypeRefData;
628
629     fn lower(self, tcx: TyCtxt) -> TypeRefData {
630         TypeRefData {
631             span: span_from_span(self.span, tcx.sess.codemap()),
632             scope: make_def_id(self.scope, &tcx.hir),
633             ref_id: self.ref_id,
634             qualname: self.qualname,
635         }
636     }
637 }
638
639 #[derive(Debug)]
640 pub struct UseData {
641     pub id: DefId,
642     pub span: SpanData,
643     pub name: String,
644     pub mod_id: Option<DefId>,
645     pub scope: DefId,
646     pub visibility: Visibility,
647 }
648
649 impl Lower for data::UseData {
650     type Target = UseData;
651
652     fn lower(self, tcx: TyCtxt) -> UseData {
653         UseData {
654             id: make_def_id(self.id, &tcx.hir),
655             span: span_from_span(self.span, tcx.sess.codemap()),
656             name: self.name,
657             mod_id: self.mod_id,
658             scope: make_def_id(self.scope, &tcx.hir),
659             visibility: self.visibility,
660         }
661     }
662 }
663
664 #[derive(Debug)]
665 pub struct UseGlobData {
666     pub id: DefId,
667     pub span: SpanData,
668     pub names: Vec<String>,
669     pub scope: DefId,
670     pub visibility: Visibility,
671 }
672
673 impl Lower for data::UseGlobData {
674     type Target = UseGlobData;
675
676     fn lower(self, tcx: TyCtxt) -> UseGlobData {
677         UseGlobData {
678             id: make_def_id(self.id, &tcx.hir),
679             span: span_from_span(self.span, tcx.sess.codemap()),
680             names: self.names,
681             scope: make_def_id(self.scope, &tcx.hir),
682             visibility: self.visibility,
683         }
684     }
685 }
686
687 /// Data for local and global variables (consts and statics).
688 #[derive(Debug)]
689 pub struct VariableData {
690     pub id: DefId,
691     pub name: String,
692     pub kind: data::VariableKind,
693     pub qualname: String,
694     pub span: SpanData,
695     pub scope: DefId,
696     pub value: String,
697     pub type_value: String,
698     pub parent: Option<DefId>,
699     pub visibility: Visibility,
700     pub docs: String,
701     pub sig: Option<Signature>,
702     pub attributes: Vec<Attribute>,
703 }
704
705 impl Lower for data::VariableData {
706     type Target = VariableData;
707
708     fn lower(self, tcx: TyCtxt) -> VariableData {
709         VariableData {
710             id: make_def_id(self.id, &tcx.hir),
711             kind: self.kind,
712             name: self.name,
713             qualname: self.qualname,
714             span: span_from_span(self.span, tcx.sess.codemap()),
715             scope: make_def_id(self.scope, &tcx.hir),
716             value: self.value,
717             type_value: self.type_value,
718             parent: self.parent,
719             visibility: self.visibility,
720             docs: self.docs,
721             sig: self.sig,
722             attributes: self.attributes.lower(tcx),
723         }
724     }
725 }
726
727 /// Data for the use of some item (e.g., the use of a local variable, which
728 /// will refer to that variables declaration (by ref_id)).
729 #[derive(Debug)]
730 pub struct VariableRefData {
731     pub name: String,
732     pub span: SpanData,
733     pub scope: DefId,
734     pub ref_id: DefId,
735 }
736
737 impl Lower for data::VariableRefData {
738     type Target = VariableRefData;
739
740     fn lower(self, tcx: TyCtxt) -> VariableRefData {
741         VariableRefData {
742             name: self.name,
743             span: span_from_span(self.span, tcx.sess.codemap()),
744             scope: make_def_id(self.scope, &tcx.hir),
745             ref_id: self.ref_id,
746         }
747     }
748 }