]> git.proxmox.com Git - rustc.git/blob - src/librustc_incremental/persist/directory.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.git] / src / librustc_incremental / persist / directory.rs
1 // Copyright 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 //! Code to convert a DefId into a DefPath (when serializing) and then
12 //! back again (when deserializing). Note that the new DefId
13 //! necessarily will not be the same as the old (and of course the
14 //! item might even be removed in the meantime).
15
16 use rustc::dep_graph::DepNode;
17 use rustc::hir::map::DefPath;
18 use rustc::hir::def_id::DefId;
19 use rustc::ty;
20 use rustc::util::nodemap::DefIdMap;
21 use rustc_serialize::{Decoder as RustcDecoder,
22 Encodable as RustcEncodable, Encoder as RustcEncoder};
23 use std::fmt::{self, Debug};
24
25 /// Index into the DefIdDirectory
26 #[derive(Copy, Clone, Debug, PartialOrd, Ord, Hash, PartialEq, Eq,
27 RustcEncodable, RustcDecodable)]
28 pub struct DefPathIndex {
29 index: u32
30 }
31
32 #[derive(RustcEncodable, RustcDecodable)]
33 pub struct DefIdDirectory {
34 // N.B. don't use Removable here because these def-ids are loaded
35 // directly without remapping, so loading them should not fail.
36 paths: Vec<DefPath>
37 }
38
39 impl DefIdDirectory {
40 pub fn new() -> DefIdDirectory {
41 DefIdDirectory { paths: vec![] }
42 }
43
44 pub fn retrace(&self, tcx: &ty::TyCtxt) -> RetracedDefIdDirectory {
45 let ids = self.paths.iter()
46 .map(|path| tcx.map.retrace_path(path))
47 .collect();
48 RetracedDefIdDirectory { ids: ids }
49 }
50 }
51
52 #[derive(Debug, RustcEncodable, RustcDecodable)]
53 pub struct RetracedDefIdDirectory {
54 ids: Vec<Option<DefId>>
55 }
56
57 impl RetracedDefIdDirectory {
58 pub fn def_id(&self, index: DefPathIndex) -> Option<DefId> {
59 self.ids[index.index as usize]
60 }
61
62 pub fn map(&self, node: DepNode<DefPathIndex>) -> Option<DepNode<DefId>> {
63 node.map_def(|&index| self.def_id(index))
64 }
65 }
66
67 pub struct DefIdDirectoryBuilder<'a,'tcx:'a> {
68 tcx: &'a ty::TyCtxt<'tcx>,
69 hash: DefIdMap<Option<DefPathIndex>>,
70 directory: DefIdDirectory,
71 }
72
73 impl<'a,'tcx> DefIdDirectoryBuilder<'a,'tcx> {
74 pub fn new(tcx: &'a ty::TyCtxt<'tcx>) -> DefIdDirectoryBuilder<'a, 'tcx> {
75 DefIdDirectoryBuilder {
76 tcx: tcx,
77 hash: DefIdMap(),
78 directory: DefIdDirectory::new()
79 }
80 }
81
82 pub fn add(&mut self, def_id: DefId) -> Option<DefPathIndex> {
83 if !def_id.is_local() {
84 // FIXME(#32015) clarify story about cross-crate dep tracking
85 return None;
86 }
87
88 let tcx = self.tcx;
89 let paths = &mut self.directory.paths;
90 self.hash.entry(def_id)
91 .or_insert_with(|| {
92 let def_path = tcx.def_path(def_id);
93 if !def_path.is_local() {
94 return None;
95 }
96 let index = paths.len() as u32;
97 paths.push(def_path);
98 Some(DefPathIndex { index: index })
99 })
100 .clone()
101 }
102
103 pub fn map(&mut self, node: DepNode<DefId>) -> Option<DepNode<DefPathIndex>> {
104 node.map_def(|&def_id| self.add(def_id))
105 }
106
107 pub fn into_directory(self) -> DefIdDirectory {
108 self.directory
109 }
110 }
111
112 impl Debug for DefIdDirectory {
113 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
114 fmt.debug_list()
115 .entries(self.paths.iter().enumerate())
116 .finish()
117 }
118 }