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.
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.
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::symbol::Symbol;
20 use data::{self, Visibility, SigElement};
22 // FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
25 fn lower(self, tcx: TyCtxt) -> Self::Target;
28 pub fn make_def_id(id: NodeId, map: &Map) -> DefId {
29 map.opt_local_def_id(id).unwrap_or(null_def_id())
32 pub fn null_def_id() -> DefId {
34 krate: CrateNum::from_u32(u32::max_value()),
35 index: DefIndex::from_u32(u32::max_value())
39 #[derive(Clone, Debug, RustcEncodable)]
41 pub file_name: String,
45 pub line_start: usize,
47 /// 1-based, character offset.
48 pub column_start: usize,
49 pub column_end: usize,
53 pub fn from_span(span: Span, cm: &CodeMap) -> SpanData {
54 let start = cm.lookup_char_pos(span.lo);
55 let end = cm.lookup_char_pos(span.hi);
58 file_name: start.file.name.clone(),
59 byte_start: span.lo.0,
61 line_start: start.line,
63 column_start: start.col.0 + 1,
64 column_end: end.col.0 + 1,
69 /// Represent an arbitrary attribute on a code element
70 #[derive(Clone, Debug, RustcEncodable)]
71 pub struct Attribute {
76 impl Lower for Vec<ast::Attribute> {
77 type Target = Vec<Attribute>;
79 fn lower(self, tcx: TyCtxt) -> Vec<Attribute> {
80 let doc = Symbol::intern("doc");
82 // Only retain real attributes. Doc comments are lowered separately.
83 .filter(|attr| attr.name() != doc)
85 // Remove the surrounding '#[..]' or '#![..]' of the pretty printed
86 // attribute. First normalize all inner attribute (#![..]) to outer
87 // ones (#[..]), then remove the two leading and the one trailing character.
88 attr.style = ast::AttrStyle::Outer;
89 let value = pprust::attribute_to_string(&attr);
90 // This str slicing works correctly, because the leading and trailing characters
91 // are in the ASCII range and thus exactly one byte each.
92 let value = value[2..value.len()-1].to_string();
96 span: SpanData::from_span(attr.span, tcx.sess.codemap()),
102 #[derive(Debug, RustcEncodable)]
103 pub struct CratePreludeData {
104 pub crate_name: String,
105 pub crate_root: String,
106 pub external_crates: Vec<data::ExternalCrateData>,
110 impl Lower for data::CratePreludeData {
111 type Target = CratePreludeData;
113 fn lower(self, tcx: TyCtxt) -> CratePreludeData {
115 crate_name: self.crate_name,
116 crate_root: self.crate_root,
117 external_crates: self.external_crates,
118 span: SpanData::from_span(self.span, tcx.sess.codemap()),
123 /// Data for enum declarations.
124 #[derive(Clone, Debug, RustcEncodable)]
125 pub struct EnumData {
129 pub qualname: String,
132 pub variants: Vec<DefId>,
133 pub visibility: Visibility,
136 pub attributes: Vec<Attribute>,
139 impl Lower for data::EnumData {
140 type Target = EnumData;
142 fn lower(self, tcx: TyCtxt) -> EnumData {
144 id: make_def_id(self.id, &tcx.hir),
147 qualname: self.qualname,
148 span: SpanData::from_span(self.span, tcx.sess.codemap()),
149 scope: make_def_id(self.scope, &tcx.hir),
150 variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
151 visibility: self.visibility,
153 sig: self.sig.lower(tcx),
154 attributes: self.attributes.lower(tcx),
159 /// Data for extern crates.
160 #[derive(Debug, RustcEncodable)]
161 pub struct ExternCrateData {
164 pub crate_num: CrateNum,
165 pub location: String,
170 impl Lower for data::ExternCrateData {
171 type Target = ExternCrateData;
173 fn lower(self, tcx: TyCtxt) -> ExternCrateData {
175 id: make_def_id(self.id, &tcx.hir),
177 crate_num: self.crate_num,
178 location: self.location,
179 span: SpanData::from_span(self.span, tcx.sess.codemap()),
180 scope: make_def_id(self.scope, &tcx.hir),
185 /// Data about a function call.
186 #[derive(Debug, RustcEncodable)]
187 pub struct FunctionCallData {
193 impl Lower for data::FunctionCallData {
194 type Target = FunctionCallData;
196 fn lower(self, tcx: TyCtxt) -> FunctionCallData {
198 span: SpanData::from_span(self.span, tcx.sess.codemap()),
199 scope: make_def_id(self.scope, &tcx.hir),
205 /// Data for all kinds of functions and methods.
206 #[derive(Clone, Debug, RustcEncodable)]
207 pub struct FunctionData {
210 pub qualname: String,
211 pub declaration: Option<DefId>,
215 pub visibility: Visibility,
216 pub parent: Option<DefId>,
219 pub attributes: Vec<Attribute>,
222 impl Lower for data::FunctionData {
223 type Target = FunctionData;
225 fn lower(self, tcx: TyCtxt) -> FunctionData {
227 id: make_def_id(self.id, &tcx.hir),
229 qualname: self.qualname,
230 declaration: self.declaration,
231 span: SpanData::from_span(self.span, tcx.sess.codemap()),
232 scope: make_def_id(self.scope, &tcx.hir),
234 visibility: self.visibility,
237 sig: self.sig.lower(tcx),
238 attributes: self.attributes.lower(tcx),
243 /// Data about a function call.
244 #[derive(Debug, RustcEncodable)]
245 pub struct FunctionRefData {
251 impl Lower for data::FunctionRefData {
252 type Target = FunctionRefData;
254 fn lower(self, tcx: TyCtxt) -> FunctionRefData {
256 span: SpanData::from_span(self.span, tcx.sess.codemap()),
257 scope: make_def_id(self.scope, &tcx.hir),
262 #[derive(Debug, RustcEncodable)]
263 pub struct ImplData {
267 pub trait_ref: Option<DefId>,
268 pub self_ref: Option<DefId>,
271 impl Lower for data::ImplData {
272 type Target = ImplData;
274 fn lower(self, tcx: TyCtxt) -> ImplData {
276 id: make_def_id(self.id, &tcx.hir),
277 span: SpanData::from_span(self.span, tcx.sess.codemap()),
278 scope: make_def_id(self.scope, &tcx.hir),
279 trait_ref: self.trait_ref,
280 self_ref: self.self_ref,
285 #[derive(Debug, RustcEncodable)]
286 pub struct InheritanceData {
292 impl Lower for data::InheritanceData {
293 type Target = InheritanceData;
295 fn lower(self, tcx: TyCtxt) -> InheritanceData {
297 span: SpanData::from_span(self.span, tcx.sess.codemap()),
298 base_id: self.base_id,
299 deriv_id: make_def_id(self.deriv_id, &tcx.hir)
304 /// Data about a macro declaration.
305 #[derive(Debug, RustcEncodable)]
306 pub struct MacroData {
309 pub qualname: String,
313 impl Lower for data::MacroData {
314 type Target = MacroData;
316 fn lower(self, tcx: TyCtxt) -> MacroData {
318 span: SpanData::from_span(self.span, tcx.sess.codemap()),
320 qualname: self.qualname,
326 /// Data about a macro use.
327 #[derive(Debug, RustcEncodable)]
328 pub struct MacroUseData {
331 pub qualname: String,
332 // Because macro expansion happens before ref-ids are determined,
333 // we use the callee span to reference the associated macro definition.
334 pub callee_span: SpanData,
338 impl Lower for data::MacroUseData {
339 type Target = MacroUseData;
341 fn lower(self, tcx: TyCtxt) -> MacroUseData {
343 span: SpanData::from_span(self.span, tcx.sess.codemap()),
345 qualname: self.qualname,
346 callee_span: SpanData::from_span(self.callee_span, tcx.sess.codemap()),
347 scope: make_def_id(self.scope, &tcx.hir),
352 /// Data about a method call.
353 #[derive(Debug, RustcEncodable)]
354 pub struct MethodCallData {
357 pub ref_id: Option<DefId>,
358 pub decl_id: Option<DefId>,
361 impl Lower for data::MethodCallData {
362 type Target = MethodCallData;
364 fn lower(self, tcx: TyCtxt) -> MethodCallData {
366 span: SpanData::from_span(self.span, tcx.sess.codemap()),
367 scope: make_def_id(self.scope, &tcx.hir),
369 decl_id: self.decl_id,
374 /// Data for method declarations (methods with a body are treated as functions).
375 #[derive(Clone, Debug, RustcEncodable)]
376 pub struct MethodData {
379 pub qualname: String,
383 pub decl_id: Option<DefId>,
384 pub visibility: Visibility,
385 pub parent: Option<DefId>,
388 pub attributes: Vec<Attribute>,
391 impl Lower for data::MethodData {
392 type Target = MethodData;
394 fn lower(self, tcx: TyCtxt) -> MethodData {
396 span: SpanData::from_span(self.span, tcx.sess.codemap()),
398 scope: make_def_id(self.scope, &tcx.hir),
399 id: make_def_id(self.id, &tcx.hir),
400 qualname: self.qualname,
402 decl_id: self.decl_id,
403 visibility: self.visibility,
406 sig: self.sig.lower(tcx),
407 attributes: self.attributes.lower(tcx),
412 /// Data for modules.
413 #[derive(Debug, RustcEncodable)]
417 pub qualname: String,
420 pub filename: String,
421 pub items: Vec<DefId>,
422 pub visibility: Visibility,
425 pub attributes: Vec<Attribute>,
428 impl Lower for data::ModData {
429 type Target = ModData;
431 fn lower(self, tcx: TyCtxt) -> ModData {
433 id: make_def_id(self.id, &tcx.hir),
435 qualname: self.qualname,
436 span: SpanData::from_span(self.span, tcx.sess.codemap()),
437 scope: make_def_id(self.scope, &tcx.hir),
438 filename: self.filename,
439 items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
440 visibility: self.visibility,
442 sig: self.sig.lower(tcx),
443 attributes: self.attributes.lower(tcx),
448 /// Data for a reference to a module.
449 #[derive(Debug, RustcEncodable)]
450 pub struct ModRefData {
453 pub ref_id: Option<DefId>,
457 impl Lower for data::ModRefData {
458 type Target = ModRefData;
460 fn lower(self, tcx: TyCtxt) -> ModRefData {
462 span: SpanData::from_span(self.span, tcx.sess.codemap()),
463 scope: make_def_id(self.scope, &tcx.hir),
465 qualname: self.qualname,
470 #[derive(Debug, RustcEncodable)]
471 pub struct StructData {
476 pub qualname: String,
479 pub fields: Vec<DefId>,
480 pub visibility: Visibility,
483 pub attributes: Vec<Attribute>,
486 impl Lower for data::StructData {
487 type Target = StructData;
489 fn lower(self, tcx: TyCtxt) -> StructData {
491 span: SpanData::from_span(self.span, tcx.sess.codemap()),
493 id: make_def_id(self.id, &tcx.hir),
494 ctor_id: make_def_id(self.ctor_id, &tcx.hir),
495 qualname: self.qualname,
496 scope: make_def_id(self.scope, &tcx.hir),
498 fields: self.fields.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
499 visibility: self.visibility,
501 sig: self.sig.lower(tcx),
502 attributes: self.attributes.lower(tcx),
507 #[derive(Debug, RustcEncodable)]
508 pub struct StructVariantData {
512 pub qualname: String,
513 pub type_value: String,
516 pub parent: Option<DefId>,
519 pub attributes: Vec<Attribute>,
522 impl Lower for data::StructVariantData {
523 type Target = StructVariantData;
525 fn lower(self, tcx: TyCtxt) -> StructVariantData {
527 span: SpanData::from_span(self.span, tcx.sess.codemap()),
529 id: make_def_id(self.id, &tcx.hir),
530 qualname: self.qualname,
531 type_value: self.type_value,
533 scope: make_def_id(self.scope, &tcx.hir),
536 sig: self.sig.lower(tcx),
537 attributes: self.attributes.lower(tcx),
542 #[derive(Debug, RustcEncodable)]
543 pub struct TraitData {
547 pub qualname: String,
550 pub items: Vec<DefId>,
551 pub visibility: Visibility,
554 pub attributes: Vec<Attribute>,
557 impl Lower for data::TraitData {
558 type Target = TraitData;
560 fn lower(self, tcx: TyCtxt) -> TraitData {
562 span: SpanData::from_span(self.span, tcx.sess.codemap()),
564 id: make_def_id(self.id, &tcx.hir),
565 qualname: self.qualname,
566 scope: make_def_id(self.scope, &tcx.hir),
568 items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
569 visibility: self.visibility,
571 sig: self.sig.lower(tcx),
572 attributes: self.attributes.lower(tcx),
577 #[derive(Debug, RustcEncodable)]
578 pub struct TupleVariantData {
582 pub qualname: String,
583 pub type_value: String,
586 pub parent: Option<DefId>,
589 pub attributes: Vec<Attribute>,
592 impl Lower for data::TupleVariantData {
593 type Target = TupleVariantData;
595 fn lower(self, tcx: TyCtxt) -> TupleVariantData {
597 span: SpanData::from_span(self.span, tcx.sess.codemap()),
598 id: make_def_id(self.id, &tcx.hir),
600 qualname: self.qualname,
601 type_value: self.type_value,
603 scope: make_def_id(self.scope, &tcx.hir),
606 sig: self.sig.lower(tcx),
607 attributes: self.attributes.lower(tcx),
612 /// Data for a typedef.
613 #[derive(Debug, RustcEncodable)]
614 pub struct TypeDefData {
618 pub qualname: String,
620 pub visibility: Visibility,
621 pub parent: Option<DefId>,
623 pub sig: Option<Signature>,
624 pub attributes: Vec<Attribute>,
627 impl Lower for data::TypeDefData {
628 type Target = TypeDefData;
630 fn lower(self, tcx: TyCtxt) -> TypeDefData {
632 id: make_def_id(self.id, &tcx.hir),
634 span: SpanData::from_span(self.span, tcx.sess.codemap()),
635 qualname: self.qualname,
637 visibility: self.visibility,
640 sig: self.sig.map(|s| s.lower(tcx)),
641 attributes: self.attributes.lower(tcx),
646 /// Data for a reference to a type or trait.
647 #[derive(Clone, Debug, RustcEncodable)]
648 pub struct TypeRefData {
651 pub ref_id: Option<DefId>,
652 pub qualname: String,
655 impl Lower for data::TypeRefData {
656 type Target = TypeRefData;
658 fn lower(self, tcx: TyCtxt) -> TypeRefData {
660 span: SpanData::from_span(self.span, tcx.sess.codemap()),
661 scope: make_def_id(self.scope, &tcx.hir),
663 qualname: self.qualname,
668 #[derive(Debug, RustcEncodable)]
673 pub mod_id: Option<DefId>,
675 pub visibility: Visibility,
678 impl Lower for data::UseData {
679 type Target = UseData;
681 fn lower(self, tcx: TyCtxt) -> UseData {
683 id: make_def_id(self.id, &tcx.hir),
684 span: SpanData::from_span(self.span, tcx.sess.codemap()),
687 scope: make_def_id(self.scope, &tcx.hir),
688 visibility: self.visibility,
693 #[derive(Debug, RustcEncodable)]
694 pub struct UseGlobData {
697 pub names: Vec<String>,
699 pub visibility: Visibility,
702 impl Lower for data::UseGlobData {
703 type Target = UseGlobData;
705 fn lower(self, tcx: TyCtxt) -> UseGlobData {
707 id: make_def_id(self.id, &tcx.hir),
708 span: SpanData::from_span(self.span, tcx.sess.codemap()),
710 scope: make_def_id(self.scope, &tcx.hir),
711 visibility: self.visibility,
716 /// Data for local and global variables (consts and statics).
717 #[derive(Debug, RustcEncodable)]
718 pub struct VariableData {
721 pub kind: data::VariableKind,
722 pub qualname: String,
726 pub type_value: String,
727 pub parent: Option<DefId>,
728 pub visibility: Visibility,
730 pub sig: Option<Signature>,
731 pub attributes: Vec<Attribute>,
734 impl Lower for data::VariableData {
735 type Target = VariableData;
737 fn lower(self, tcx: TyCtxt) -> VariableData {
739 id: make_def_id(self.id, &tcx.hir),
742 qualname: self.qualname,
743 span: SpanData::from_span(self.span, tcx.sess.codemap()),
744 scope: make_def_id(self.scope, &tcx.hir),
746 type_value: self.type_value,
748 visibility: self.visibility,
750 sig: self.sig.map(|s| s.lower(tcx)),
751 attributes: self.attributes.lower(tcx),
756 /// Data for the use of some item (e.g., the use of a local variable, which
757 /// will refer to that variables declaration (by ref_id)).
758 #[derive(Debug, RustcEncodable)]
759 pub struct VariableRefData {
766 impl Lower for data::VariableRefData {
767 type Target = VariableRefData;
769 fn lower(self, tcx: TyCtxt) -> VariableRefData {
772 span: SpanData::from_span(self.span, tcx.sess.codemap()),
773 scope: make_def_id(self.scope, &tcx.hir),
779 #[derive(Clone, Debug, RustcEncodable)]
780 pub struct Signature {
783 // These identify the main identifier for the defintion as byte offsets into
784 // `text`. E.g., of `foo` in `pub fn foo(...)`
785 pub ident_start: usize,
786 pub ident_end: usize,
787 pub defs: Vec<SigElement>,
788 pub refs: Vec<SigElement>,
791 impl Lower for data::Signature {
792 type Target = Signature;
794 fn lower(self, tcx: TyCtxt) -> Signature {
796 span: SpanData::from_span(self.span, tcx.sess.codemap()),
798 ident_start: self.ident_start,
799 ident_end: self.ident_end,