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 std::path::PathBuf;
22 use data::{self, Visibility, SigElement};
24 use rls_data::{SpanData, CratePreludeData};
26 // FIXME: this should be pub(crate), but the current snapshot doesn't allow it yet
29 fn lower(self, tcx: TyCtxt) -> Self::Target;
32 pub fn make_def_id(id: NodeId, map: &Map) -> DefId {
33 map.opt_local_def_id(id).unwrap_or(null_def_id())
36 pub fn null_def_id() -> DefId {
38 krate: CrateNum::from_u32(u32::max_value()),
39 index: DefIndex::from_u32(u32::max_value())
43 pub fn span_from_span(span: Span, cm: &CodeMap) -> SpanData {
44 let start = cm.lookup_char_pos(span.lo);
45 let end = cm.lookup_char_pos(span.hi);
48 file_name: start.file.name.clone().into(),
49 byte_start: span.lo.0,
51 line_start: start.line,
53 column_start: start.col.0 + 1,
54 column_end: end.col.0 + 1,
58 /// Represent an arbitrary attribute on a code element
59 #[derive(Clone, Debug, RustcEncodable)]
60 pub struct Attribute {
65 impl Lower for Vec<ast::Attribute> {
66 type Target = Vec<Attribute>;
68 fn lower(self, tcx: TyCtxt) -> Vec<Attribute> {
69 let doc = Symbol::intern("doc");
71 // Only retain real attributes. Doc comments are lowered separately.
72 .filter(|attr| attr.name() != doc)
74 // Remove the surrounding '#[..]' or '#![..]' of the pretty printed
75 // attribute. First normalize all inner attribute (#![..]) to outer
76 // ones (#[..]), then remove the two leading and the one trailing character.
77 attr.style = ast::AttrStyle::Outer;
78 let value = pprust::attribute_to_string(&attr);
79 // This str slicing works correctly, because the leading and trailing characters
80 // are in the ASCII range and thus exactly one byte each.
81 let value = value[2..value.len()-1].to_string();
85 span: span_from_span(attr.span, tcx.sess.codemap()),
91 impl Lower for data::CratePreludeData {
92 type Target = CratePreludeData;
94 fn lower(self, tcx: TyCtxt) -> CratePreludeData {
96 crate_name: self.crate_name,
97 crate_root: self.crate_root,
98 external_crates: self.external_crates,
99 span: span_from_span(self.span, tcx.sess.codemap()),
104 /// Data for enum declarations.
105 #[derive(Clone, Debug, RustcEncodable)]
106 pub struct EnumData {
110 pub qualname: String,
113 pub variants: Vec<DefId>,
114 pub visibility: Visibility,
117 pub attributes: Vec<Attribute>,
120 impl Lower for data::EnumData {
121 type Target = EnumData;
123 fn lower(self, tcx: TyCtxt) -> EnumData {
125 id: make_def_id(self.id, &tcx.hir),
128 qualname: self.qualname,
129 span: span_from_span(self.span, tcx.sess.codemap()),
130 scope: make_def_id(self.scope, &tcx.hir),
131 variants: self.variants.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
132 visibility: self.visibility,
134 sig: self.sig.lower(tcx),
135 attributes: self.attributes.lower(tcx),
140 /// Data for extern crates.
141 #[derive(Debug, RustcEncodable)]
142 pub struct ExternCrateData {
145 pub crate_num: CrateNum,
146 pub location: String,
151 impl Lower for data::ExternCrateData {
152 type Target = ExternCrateData;
154 fn lower(self, tcx: TyCtxt) -> ExternCrateData {
156 id: make_def_id(self.id, &tcx.hir),
158 crate_num: self.crate_num,
159 location: self.location,
160 span: span_from_span(self.span, tcx.sess.codemap()),
161 scope: make_def_id(self.scope, &tcx.hir),
166 /// Data about a function call.
167 #[derive(Debug, RustcEncodable)]
168 pub struct FunctionCallData {
174 impl Lower for data::FunctionCallData {
175 type Target = FunctionCallData;
177 fn lower(self, tcx: TyCtxt) -> FunctionCallData {
179 span: span_from_span(self.span, tcx.sess.codemap()),
180 scope: make_def_id(self.scope, &tcx.hir),
186 /// Data for all kinds of functions and methods.
187 #[derive(Clone, Debug, RustcEncodable)]
188 pub struct FunctionData {
191 pub qualname: String,
192 pub declaration: Option<DefId>,
196 pub visibility: Visibility,
197 pub parent: Option<DefId>,
200 pub attributes: Vec<Attribute>,
203 impl Lower for data::FunctionData {
204 type Target = FunctionData;
206 fn lower(self, tcx: TyCtxt) -> FunctionData {
208 id: make_def_id(self.id, &tcx.hir),
210 qualname: self.qualname,
211 declaration: self.declaration,
212 span: span_from_span(self.span, tcx.sess.codemap()),
213 scope: make_def_id(self.scope, &tcx.hir),
215 visibility: self.visibility,
218 sig: self.sig.lower(tcx),
219 attributes: self.attributes.lower(tcx),
224 /// Data about a function call.
225 #[derive(Debug, RustcEncodable)]
226 pub struct FunctionRefData {
232 impl Lower for data::FunctionRefData {
233 type Target = FunctionRefData;
235 fn lower(self, tcx: TyCtxt) -> FunctionRefData {
237 span: span_from_span(self.span, tcx.sess.codemap()),
238 scope: make_def_id(self.scope, &tcx.hir),
243 #[derive(Debug, RustcEncodable)]
244 pub struct ImplData {
248 pub trait_ref: Option<DefId>,
249 pub self_ref: Option<DefId>,
252 impl Lower for data::ImplData {
253 type Target = ImplData;
255 fn lower(self, tcx: TyCtxt) -> ImplData {
257 id: make_def_id(self.id, &tcx.hir),
258 span: span_from_span(self.span, tcx.sess.codemap()),
259 scope: make_def_id(self.scope, &tcx.hir),
260 trait_ref: self.trait_ref,
261 self_ref: self.self_ref,
266 #[derive(Debug, RustcEncodable)]
267 pub struct InheritanceData {
273 impl Lower for data::InheritanceData {
274 type Target = InheritanceData;
276 fn lower(self, tcx: TyCtxt) -> InheritanceData {
278 span: span_from_span(self.span, tcx.sess.codemap()),
279 base_id: self.base_id,
280 deriv_id: make_def_id(self.deriv_id, &tcx.hir)
285 /// Data about a macro declaration.
286 #[derive(Debug, RustcEncodable)]
287 pub struct MacroData {
290 pub qualname: String,
294 impl Lower for data::MacroData {
295 type Target = MacroData;
297 fn lower(self, tcx: TyCtxt) -> MacroData {
299 span: span_from_span(self.span, tcx.sess.codemap()),
301 qualname: self.qualname,
307 /// Data about a macro use.
308 #[derive(Debug, RustcEncodable)]
309 pub struct MacroUseData {
312 pub qualname: String,
313 // Because macro expansion happens before ref-ids are determined,
314 // we use the callee span to reference the associated macro definition.
315 pub callee_span: SpanData,
319 impl Lower for data::MacroUseData {
320 type Target = MacroUseData;
322 fn lower(self, tcx: TyCtxt) -> MacroUseData {
324 span: span_from_span(self.span, tcx.sess.codemap()),
326 qualname: self.qualname,
327 callee_span: span_from_span(self.callee_span, tcx.sess.codemap()),
328 scope: make_def_id(self.scope, &tcx.hir),
333 /// Data about a method call.
334 #[derive(Debug, RustcEncodable)]
335 pub struct MethodCallData {
338 pub ref_id: Option<DefId>,
339 pub decl_id: Option<DefId>,
342 impl Lower for data::MethodCallData {
343 type Target = MethodCallData;
345 fn lower(self, tcx: TyCtxt) -> MethodCallData {
347 span: span_from_span(self.span, tcx.sess.codemap()),
348 scope: make_def_id(self.scope, &tcx.hir),
350 decl_id: self.decl_id,
355 /// Data for method declarations (methods with a body are treated as functions).
356 #[derive(Clone, Debug, RustcEncodable)]
357 pub struct MethodData {
360 pub qualname: String,
364 pub decl_id: Option<DefId>,
365 pub visibility: Visibility,
366 pub parent: Option<DefId>,
369 pub attributes: Vec<Attribute>,
372 impl Lower for data::MethodData {
373 type Target = MethodData;
375 fn lower(self, tcx: TyCtxt) -> MethodData {
377 span: span_from_span(self.span, tcx.sess.codemap()),
379 scope: make_def_id(self.scope, &tcx.hir),
380 id: make_def_id(self.id, &tcx.hir),
381 qualname: self.qualname,
383 decl_id: self.decl_id,
384 visibility: self.visibility,
387 sig: self.sig.lower(tcx),
388 attributes: self.attributes.lower(tcx),
393 /// Data for modules.
394 #[derive(Debug, RustcEncodable)]
398 pub qualname: String,
401 pub filename: String,
402 pub items: Vec<DefId>,
403 pub visibility: Visibility,
406 pub attributes: Vec<Attribute>,
409 impl Lower for data::ModData {
410 type Target = ModData;
412 fn lower(self, tcx: TyCtxt) -> ModData {
414 id: make_def_id(self.id, &tcx.hir),
416 qualname: self.qualname,
417 span: span_from_span(self.span, tcx.sess.codemap()),
418 scope: make_def_id(self.scope, &tcx.hir),
419 filename: self.filename,
420 items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
421 visibility: self.visibility,
423 sig: self.sig.lower(tcx),
424 attributes: self.attributes.lower(tcx),
429 /// Data for a reference to a module.
430 #[derive(Debug, RustcEncodable)]
431 pub struct ModRefData {
434 pub ref_id: Option<DefId>,
438 impl Lower for data::ModRefData {
439 type Target = ModRefData;
441 fn lower(self, tcx: TyCtxt) -> ModRefData {
443 span: span_from_span(self.span, tcx.sess.codemap()),
444 scope: make_def_id(self.scope, &tcx.hir),
446 qualname: self.qualname,
451 #[derive(Debug, RustcEncodable)]
452 pub struct StructData {
457 pub qualname: String,
460 pub fields: Vec<DefId>,
461 pub visibility: Visibility,
464 pub attributes: Vec<Attribute>,
467 impl Lower for data::StructData {
468 type Target = StructData;
470 fn lower(self, tcx: TyCtxt) -> StructData {
472 span: span_from_span(self.span, tcx.sess.codemap()),
474 id: make_def_id(self.id, &tcx.hir),
475 ctor_id: make_def_id(self.ctor_id, &tcx.hir),
476 qualname: self.qualname,
477 scope: make_def_id(self.scope, &tcx.hir),
479 fields: self.fields.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
480 visibility: self.visibility,
482 sig: self.sig.lower(tcx),
483 attributes: self.attributes.lower(tcx),
488 #[derive(Debug, RustcEncodable)]
489 pub struct StructVariantData {
493 pub qualname: String,
494 pub type_value: String,
497 pub parent: Option<DefId>,
500 pub attributes: Vec<Attribute>,
503 impl Lower for data::StructVariantData {
504 type Target = StructVariantData;
506 fn lower(self, tcx: TyCtxt) -> StructVariantData {
508 span: span_from_span(self.span, tcx.sess.codemap()),
510 id: make_def_id(self.id, &tcx.hir),
511 qualname: self.qualname,
512 type_value: self.type_value,
514 scope: make_def_id(self.scope, &tcx.hir),
517 sig: self.sig.lower(tcx),
518 attributes: self.attributes.lower(tcx),
523 #[derive(Debug, RustcEncodable)]
524 pub struct TraitData {
528 pub qualname: String,
531 pub items: Vec<DefId>,
532 pub visibility: Visibility,
535 pub attributes: Vec<Attribute>,
538 impl Lower for data::TraitData {
539 type Target = TraitData;
541 fn lower(self, tcx: TyCtxt) -> TraitData {
543 span: span_from_span(self.span, tcx.sess.codemap()),
545 id: make_def_id(self.id, &tcx.hir),
546 qualname: self.qualname,
547 scope: make_def_id(self.scope, &tcx.hir),
549 items: self.items.into_iter().map(|id| make_def_id(id, &tcx.hir)).collect(),
550 visibility: self.visibility,
552 sig: self.sig.lower(tcx),
553 attributes: self.attributes.lower(tcx),
558 #[derive(Debug, RustcEncodable)]
559 pub struct TupleVariantData {
563 pub qualname: String,
564 pub type_value: String,
567 pub parent: Option<DefId>,
570 pub attributes: Vec<Attribute>,
573 impl Lower for data::TupleVariantData {
574 type Target = TupleVariantData;
576 fn lower(self, tcx: TyCtxt) -> TupleVariantData {
578 span: span_from_span(self.span, tcx.sess.codemap()),
579 id: make_def_id(self.id, &tcx.hir),
581 qualname: self.qualname,
582 type_value: self.type_value,
584 scope: make_def_id(self.scope, &tcx.hir),
587 sig: self.sig.lower(tcx),
588 attributes: self.attributes.lower(tcx),
593 /// Data for a typedef.
594 #[derive(Debug, RustcEncodable)]
595 pub struct TypeDefData {
599 pub qualname: String,
601 pub visibility: Visibility,
602 pub parent: Option<DefId>,
604 pub sig: Option<Signature>,
605 pub attributes: Vec<Attribute>,
608 impl Lower for data::TypeDefData {
609 type Target = TypeDefData;
611 fn lower(self, tcx: TyCtxt) -> TypeDefData {
613 id: make_def_id(self.id, &tcx.hir),
615 span: span_from_span(self.span, tcx.sess.codemap()),
616 qualname: self.qualname,
618 visibility: self.visibility,
621 sig: self.sig.map(|s| s.lower(tcx)),
622 attributes: self.attributes.lower(tcx),
627 /// Data for a reference to a type or trait.
628 #[derive(Clone, Debug, RustcEncodable)]
629 pub struct TypeRefData {
632 pub ref_id: Option<DefId>,
633 pub qualname: String,
636 impl Lower for data::TypeRefData {
637 type Target = TypeRefData;
639 fn lower(self, tcx: TyCtxt) -> TypeRefData {
641 span: span_from_span(self.span, tcx.sess.codemap()),
642 scope: make_def_id(self.scope, &tcx.hir),
644 qualname: self.qualname,
649 #[derive(Debug, RustcEncodable)]
654 pub mod_id: Option<DefId>,
656 pub visibility: Visibility,
659 impl Lower for data::UseData {
660 type Target = UseData;
662 fn lower(self, tcx: TyCtxt) -> UseData {
664 id: make_def_id(self.id, &tcx.hir),
665 span: span_from_span(self.span, tcx.sess.codemap()),
668 scope: make_def_id(self.scope, &tcx.hir),
669 visibility: self.visibility,
674 #[derive(Debug, RustcEncodable)]
675 pub struct UseGlobData {
678 pub names: Vec<String>,
680 pub visibility: Visibility,
683 impl Lower for data::UseGlobData {
684 type Target = UseGlobData;
686 fn lower(self, tcx: TyCtxt) -> UseGlobData {
688 id: make_def_id(self.id, &tcx.hir),
689 span: span_from_span(self.span, tcx.sess.codemap()),
691 scope: make_def_id(self.scope, &tcx.hir),
692 visibility: self.visibility,
697 /// Data for local and global variables (consts and statics).
698 #[derive(Debug, RustcEncodable)]
699 pub struct VariableData {
702 pub kind: data::VariableKind,
703 pub qualname: String,
707 pub type_value: String,
708 pub parent: Option<DefId>,
709 pub visibility: Visibility,
711 pub sig: Option<Signature>,
712 pub attributes: Vec<Attribute>,
715 impl Lower for data::VariableData {
716 type Target = VariableData;
718 fn lower(self, tcx: TyCtxt) -> VariableData {
720 id: make_def_id(self.id, &tcx.hir),
723 qualname: self.qualname,
724 span: span_from_span(self.span, tcx.sess.codemap()),
725 scope: make_def_id(self.scope, &tcx.hir),
727 type_value: self.type_value,
729 visibility: self.visibility,
731 sig: self.sig.map(|s| s.lower(tcx)),
732 attributes: self.attributes.lower(tcx),
737 /// Data for the use of some item (e.g., the use of a local variable, which
738 /// will refer to that variables declaration (by ref_id)).
739 #[derive(Debug, RustcEncodable)]
740 pub struct VariableRefData {
747 impl Lower for data::VariableRefData {
748 type Target = VariableRefData;
750 fn lower(self, tcx: TyCtxt) -> VariableRefData {
753 span: span_from_span(self.span, tcx.sess.codemap()),
754 scope: make_def_id(self.scope, &tcx.hir),
760 #[derive(Clone, Debug, RustcEncodable)]
761 pub struct Signature {
764 // These identify the main identifier for the defintion as byte offsets into
765 // `text`. E.g., of `foo` in `pub fn foo(...)`
766 pub ident_start: usize,
767 pub ident_end: usize,
768 pub defs: Vec<SigElement>,
769 pub refs: Vec<SigElement>,
772 impl Lower for data::Signature {
773 type Target = Signature;
775 fn lower(self, tcx: TyCtxt) -> Signature {
777 span: span_from_span(self.span, tcx.sess.codemap()),
779 ident_start: self.ident_start,
780 ident_end: self.ident_end,