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.
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 //! 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).
16 use rustc
::dep_graph
::DepNode
;
17 use rustc
::hir
::map
::DefPath
;
18 use rustc
::hir
::def_id
::DefId
;
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}
;
25 /// Index into the DefIdDirectory
26 #[derive(Copy, Clone, Debug, PartialOrd, Ord, Hash, PartialEq, Eq,
27 RustcEncodable
, RustcDecodable
)]
28 pub struct DefPathIndex
{
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.
40 pub fn new() -> DefIdDirectory
{
41 DefIdDirectory { paths: vec![] }
44 pub fn retrace(&self, tcx
: &ty
::TyCtxt
) -> RetracedDefIdDirectory
{
45 let ids
= self.paths
.iter()
46 .map(|path
| tcx
.map
.retrace_path(path
))
48 RetracedDefIdDirectory { ids: ids }
52 #[derive(Debug, RustcEncodable, RustcDecodable)]
53 pub struct RetracedDefIdDirectory
{
54 ids
: Vec
<Option
<DefId
>>
57 impl RetracedDefIdDirectory
{
58 pub fn def_id(&self, index
: DefPathIndex
) -> Option
<DefId
> {
59 self.ids
[index
.index
as usize]
62 pub fn map(&self, node
: DepNode
<DefPathIndex
>) -> Option
<DepNode
<DefId
>> {
63 node
.map_def(|&index
| self.def_id(index
))
67 pub struct DefIdDirectoryBuilder
<'a
,'tcx
:'a
> {
68 tcx
: &'a ty
::TyCtxt
<'tcx
>,
69 hash
: DefIdMap
<Option
<DefPathIndex
>>,
70 directory
: DefIdDirectory
,
73 impl<'a
,'tcx
> DefIdDirectoryBuilder
<'a
,'tcx
> {
74 pub fn new(tcx
: &'a ty
::TyCtxt
<'tcx
>) -> DefIdDirectoryBuilder
<'a
, 'tcx
> {
75 DefIdDirectoryBuilder
{
78 directory
: DefIdDirectory
::new()
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
89 let paths
= &mut self.directory
.paths
;
90 self.hash
.entry(def_id
)
92 let def_path
= tcx
.def_path(def_id
);
93 if !def_path
.is_local() {
96 let index
= paths
.len() as u32;
98 Some(DefPathIndex { index: index }
)
103 pub fn map(&mut self, node
: DepNode
<DefId
>) -> Option
<DepNode
<DefPathIndex
>> {
104 node
.map_def(|&def_id
| self.add(def_id
))
107 pub fn into_directory(self) -> DefIdDirectory
{
112 impl Debug
for DefIdDirectory
{
113 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> Result
<(), fmt
::Error
> {
115 .entries(self.paths
.iter().enumerate())