]>
Commit | Line | Data |
---|---|---|
c34b1796 | 1 | // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT |
223e47cc LB |
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 | ||
54a0048b | 11 | use rustc::hir::map as ast_map; |
92a42be0 | 12 | |
5bcae85e | 13 | use rustc::hir::intravisit::{Visitor, IdRangeComputingVisitor, IdRange}; |
e9174d1e | 14 | |
9e0c209e SL |
15 | use cstore::CrateMetadata; |
16 | use encoder::EncodeContext; | |
17 | use schema::*; | |
92a42be0 | 18 | |
9e0c209e SL |
19 | use rustc::middle::cstore::{InlinedItem, InlinedItemRef}; |
20 | use rustc::middle::const_qualif::ConstQualif; | |
54a0048b SL |
21 | use rustc::hir::def::{self, Def}; |
22 | use rustc::hir::def_id::DefId; | |
9e0c209e | 23 | use rustc::ty::{self, TyCtxt, Ty}; |
1a4d82fc | 24 | |
3157f602 | 25 | use syntax::ast; |
5bcae85e | 26 | |
9e0c209e | 27 | use rustc_serialize::Encodable; |
223e47cc | 28 | |
9e0c209e SL |
29 | #[derive(RustcEncodable, RustcDecodable)] |
30 | pub struct Ast<'tcx> { | |
31 | id_range: IdRange, | |
32 | item: Lazy<InlinedItem>, | |
33 | side_tables: LazySeq<(ast::NodeId, TableEntry<'tcx>)> | |
223e47cc LB |
34 | } |
35 | ||
9e0c209e SL |
36 | #[derive(RustcEncodable, RustcDecodable)] |
37 | enum TableEntry<'tcx> { | |
38 | Def(Def), | |
39 | NodeType(Ty<'tcx>), | |
40 | ItemSubsts(ty::ItemSubsts<'tcx>), | |
41 | Adjustment(ty::adjustment::AutoAdjustment<'tcx>), | |
42 | ConstQualif(ConstQualif) | |
223e47cc LB |
43 | } |
44 | ||
9e0c209e SL |
45 | impl<'a, 'tcx> EncodeContext<'a, 'tcx> { |
46 | pub fn encode_inlined_item(&mut self, ii: InlinedItemRef) -> Lazy<Ast<'tcx>> { | |
47 | let mut id_visitor = IdRangeComputingVisitor::new(); | |
48 | match ii { | |
49 | InlinedItemRef::Item(_, i) => id_visitor.visit_item(i), | |
50 | InlinedItemRef::TraitItem(_, ti) => id_visitor.visit_trait_item(ti), | |
51 | InlinedItemRef::ImplItem(_, ii) => id_visitor.visit_impl_item(ii) | |
223e47cc | 52 | } |
223e47cc | 53 | |
9e0c209e SL |
54 | let ii_pos = self.position(); |
55 | ii.encode(self).unwrap(); | |
56 | ||
57 | let tables_pos = self.position(); | |
58 | let tables_count = { | |
59 | let mut visitor = SideTableEncodingIdVisitor { | |
60 | ecx: self, | |
61 | count: 0 | |
62 | }; | |
63 | match ii { | |
64 | InlinedItemRef::Item(_, i) => visitor.visit_item(i), | |
65 | InlinedItemRef::TraitItem(_, ti) => visitor.visit_trait_item(ti), | |
66 | InlinedItemRef::ImplItem(_, ii) => visitor.visit_impl_item(ii) | |
e9174d1e | 67 | } |
9e0c209e SL |
68 | visitor.count |
69 | }; | |
1a4d82fc | 70 | |
9e0c209e SL |
71 | self.lazy(&Ast { |
72 | id_range: id_visitor.result(), | |
73 | item: Lazy::with_position(ii_pos), | |
74 | side_tables: LazySeq::with_position_and_length(tables_pos, tables_count) | |
75 | }) | |
1a4d82fc JJ |
76 | } |
77 | } | |
78 | ||
9e0c209e SL |
79 | struct SideTableEncodingIdVisitor<'a, 'b:'a, 'tcx:'b> { |
80 | ecx: &'a mut EncodeContext<'b, 'tcx>, | |
81 | count: usize | |
1a4d82fc JJ |
82 | } |
83 | ||
9e0c209e | 84 | impl<'a, 'b, 'tcx, 'v> Visitor<'v> for SideTableEncodingIdVisitor<'a, 'b, 'tcx> { |
1a4d82fc | 85 | fn visit_id(&mut self, id: ast::NodeId) { |
9e0c209e | 86 | debug!("Encoding side tables for id {}", id); |
223e47cc | 87 | |
9e0c209e SL |
88 | let tcx = self.ecx.tcx; |
89 | let mut encode = |entry: Option<TableEntry>| { | |
90 | if let Some(entry) = entry { | |
91 | (id, entry).encode(self.ecx).unwrap(); | |
92 | self.count += 1; | |
223e47cc | 93 | } |
9e0c209e | 94 | }; |
1a4d82fc | 95 | |
9e0c209e SL |
96 | encode(tcx.expect_def_or_none(id).map(TableEntry::Def)); |
97 | encode(tcx.node_types().get(&id).cloned().map(TableEntry::NodeType)); | |
98 | encode(tcx.tables.borrow().item_substs.get(&id).cloned().map(TableEntry::ItemSubsts)); | |
99 | encode(tcx.tables.borrow().adjustments.get(&id).cloned().map(TableEntry::Adjustment)); | |
100 | encode(tcx.const_qualif_map.borrow().get(&id).cloned().map(TableEntry::ConstQualif)); | |
223e47cc LB |
101 | } |
102 | } | |
103 | ||
9e0c209e SL |
104 | /// Decodes an item from its AST in the cdata's metadata and adds it to the |
105 | /// ast-map. | |
106 | pub fn decode_inlined_item<'a, 'tcx>(cdata: &CrateMetadata, | |
107 | tcx: TyCtxt<'a, 'tcx, 'tcx>, | |
108 | parent_def_path: ast_map::DefPath, | |
109 | parent_did: DefId, | |
110 | ast: Ast<'tcx>, | |
111 | orig_did: DefId) | |
112 | -> &'tcx InlinedItem { | |
113 | debug!("> Decoding inlined fn: {:?}", tcx.item_path_str(orig_did)); | |
223e47cc | 114 | |
9e0c209e SL |
115 | let cnt = ast.id_range.max.as_usize() - ast.id_range.min.as_usize(); |
116 | let start = tcx.sess.reserve_node_ids(cnt); | |
117 | let id_ranges = [ast.id_range, IdRange { | |
118 | min: start, | |
119 | max: ast::NodeId::new(start.as_usize() + cnt) | |
120 | }]; | |
223e47cc | 121 | |
9e0c209e SL |
122 | let ii = ast.item.decode((cdata, tcx, id_ranges)); |
123 | let ii = ast_map::map_decoded_item(&tcx.map, | |
124 | parent_def_path, | |
125 | parent_did, | |
126 | ii, | |
127 | tcx.sess.next_node_id()); | |
b039eaaf | 128 | |
b039eaaf | 129 | let item_node_id = match ii { |
5bcae85e | 130 | &InlinedItem::Item(_, ref i) => i.id, |
b039eaaf | 131 | &InlinedItem::TraitItem(_, ref ti) => ti.id, |
9e0c209e | 132 | &InlinedItem::ImplItem(_, ref ii) => ii.id |
b039eaaf | 133 | }; |
9e0c209e SL |
134 | let inlined_did = tcx.map.local_def_id(item_node_id); |
135 | tcx.register_item_type(inlined_did, tcx.lookup_item_type(orig_did)); | |
b039eaaf | 136 | |
9e0c209e SL |
137 | for (id, entry) in ast.side_tables.decode((cdata, tcx, id_ranges)) { |
138 | match entry { | |
139 | TableEntry::Def(def) => { | |
140 | tcx.def_map.borrow_mut().insert(id, def::PathResolution::new(def)); | |
b039eaaf | 141 | } |
9e0c209e SL |
142 | TableEntry::NodeType(ty) => { |
143 | tcx.node_type_insert(id, ty); | |
b039eaaf | 144 | } |
9e0c209e SL |
145 | TableEntry::ItemSubsts(item_substs) => { |
146 | tcx.tables.borrow_mut().item_substs.insert(id, item_substs); | |
a7813a04 | 147 | } |
9e0c209e SL |
148 | TableEntry::Adjustment(adj) => { |
149 | tcx.tables.borrow_mut().adjustments.insert(id, adj); | |
a7813a04 | 150 | } |
9e0c209e SL |
151 | TableEntry::ConstQualif(qualif) => { |
152 | tcx.const_qualif_map.borrow_mut().insert(id, qualif); | |
a7813a04 | 153 | } |
223e47cc | 154 | } |
9e0c209e SL |
155 | } |
156 | ||
157 | ii | |
223e47cc | 158 | } |