mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Definitions: Extract DefPath interning into its own data structure.
This commit is contained in:
parent
87b407136b
commit
8e34a8e422
@ -8,15 +8,6 @@
|
|||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
|
||||||
use rustc_data_structures::stable_hasher::StableHasher;
|
|
||||||
use std::fmt::Write;
|
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use syntax::ast;
|
|
||||||
use syntax::symbol::{Symbol, InternedString};
|
|
||||||
use ty::TyCtxt;
|
|
||||||
use util::nodemap::NodeMap;
|
|
||||||
|
|
||||||
//! For each definition, we track the following data. A definition
|
//! For each definition, we track the following data. A definition
|
||||||
//! here is defined somewhat circularly as "something with a def-id",
|
//! here is defined somewhat circularly as "something with a def-id",
|
||||||
@ -25,11 +16,84 @@ use util::nodemap::NodeMap;
|
|||||||
//! expressions) that are mostly just leftovers.
|
//! expressions) that are mostly just leftovers.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
|
||||||
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
|
use rustc_data_structures::stable_hasher::StableHasher;
|
||||||
|
use serialize::{Encodable, Decodable, Encoder, Decoder};
|
||||||
|
use std::fmt::Write;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
use syntax::ast;
|
||||||
|
use syntax::symbol::{Symbol, InternedString};
|
||||||
|
use ty::TyCtxt;
|
||||||
|
use util::nodemap::NodeMap;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct DefPathTable {
|
||||||
|
index_to_key: Vec<DefKey>,
|
||||||
|
key_to_index: FxHashMap<DefKey, DefIndex>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DefPathTable {
|
||||||
|
fn insert(&mut self, key: DefKey) -> DefIndex {
|
||||||
|
let index = DefIndex::new(self.index_to_key.len());
|
||||||
|
debug!("DefPathTable::insert() - {:?} <-> {:?}", key, index);
|
||||||
|
self.index_to_key.push(key.clone());
|
||||||
|
self.key_to_index.insert(key, index);
|
||||||
|
index
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn def_key(&self, index: DefIndex) -> DefKey {
|
||||||
|
self.index_to_key[index.as_usize()].clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn def_index_for_def_key(&self, key: &DefKey) -> Option<DefIndex> {
|
||||||
|
self.key_to_index.get(key).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn contains_key(&self, key: &DefKey) -> bool {
|
||||||
|
self.key_to_index.contains_key(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the path from the crate root to `index`. The root
|
||||||
|
/// nodes are not included in the path (i.e., this will be an
|
||||||
|
/// empty vector for the crate root). For an inlined item, this
|
||||||
|
/// will be the path of the item in the external crate (but the
|
||||||
|
/// path will begin with the path to the external crate).
|
||||||
|
pub fn def_path(&self, index: DefIndex) -> DefPath {
|
||||||
|
DefPath::make(LOCAL_CRATE, index, |p| self.def_key(p))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Encodable for DefPathTable {
|
||||||
|
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
|
||||||
|
self.index_to_key.encode(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for DefPathTable {
|
||||||
|
fn decode<D: Decoder>(d: &mut D) -> Result<DefPathTable, D::Error> {
|
||||||
|
let index_to_key: Vec<DefKey> = Decodable::decode(d)?;
|
||||||
|
let key_to_index = index_to_key.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(index, key)| (key.clone(), DefIndex::new(index)))
|
||||||
|
.collect();
|
||||||
|
Ok(DefPathTable {
|
||||||
|
index_to_key: index_to_key,
|
||||||
|
key_to_index: key_to_index,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// The definition table containing node definitions
|
/// The definition table containing node definitions
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Definitions {
|
pub struct Definitions {
|
||||||
data: Vec<DefKey>,
|
table: DefPathTable,
|
||||||
key_map: FxHashMap<DefKey, DefIndex>,
|
|
||||||
node_to_def_index: NodeMap<DefIndex>,
|
node_to_def_index: NodeMap<DefIndex>,
|
||||||
def_index_to_node: Vec<ast::NodeId>,
|
def_index_to_node: Vec<ast::NodeId>,
|
||||||
}
|
}
|
||||||
@ -214,8 +278,10 @@ impl Definitions {
|
|||||||
/// Create new empty definition map.
|
/// Create new empty definition map.
|
||||||
pub fn new() -> Definitions {
|
pub fn new() -> Definitions {
|
||||||
Definitions {
|
Definitions {
|
||||||
data: vec![],
|
table: DefPathTable {
|
||||||
key_map: FxHashMap(),
|
index_to_key: vec![],
|
||||||
|
key_to_index: FxHashMap(),
|
||||||
|
},
|
||||||
node_to_def_index: NodeMap(),
|
node_to_def_index: NodeMap(),
|
||||||
def_index_to_node: vec![],
|
def_index_to_node: vec![],
|
||||||
}
|
}
|
||||||
@ -223,15 +289,15 @@ impl Definitions {
|
|||||||
|
|
||||||
/// Get the number of definitions.
|
/// Get the number of definitions.
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.data.len()
|
self.def_index_to_node.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn def_key(&self, index: DefIndex) -> DefKey {
|
pub fn def_key(&self, index: DefIndex) -> DefKey {
|
||||||
self.data[index.as_usize()].key.clone()
|
self.table.def_key(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn def_index_for_def_key(&self, key: DefKey) -> Option<DefIndex> {
|
pub fn def_index_for_def_key(&self, key: DefKey) -> Option<DefIndex> {
|
||||||
self.key_map.get(&key).cloned()
|
self.table.def_index_for_def_key(&key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the path from the crate root to `index`. The root
|
/// Returns the path from the crate root to `index`. The root
|
||||||
@ -257,8 +323,7 @@ impl Definitions {
|
|||||||
|
|
||||||
pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
|
pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
|
||||||
if def_id.krate == LOCAL_CRATE {
|
if def_id.krate == LOCAL_CRATE {
|
||||||
assert!(def_id.index.as_usize() < self.data.len());
|
assert!(def_id.index.as_usize() < self.def_index_to_node.len());
|
||||||
// Some(self.data[def_id.index.as_usize()].node_id)
|
|
||||||
Some(self.def_index_to_node[def_id.index.as_usize()])
|
Some(self.def_index_to_node[def_id.index.as_usize()])
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -278,7 +343,7 @@ impl Definitions {
|
|||||||
"adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
|
"adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
|
||||||
node_id,
|
node_id,
|
||||||
data,
|
data,
|
||||||
self.data[self.node_to_def_index[&node_id].as_usize()]);
|
self.table.def_key(self.node_to_def_index[&node_id]));
|
||||||
|
|
||||||
assert!(parent.is_some() ^ match data {
|
assert!(parent.is_some() ^ match data {
|
||||||
DefPathData::CrateRoot | DefPathData::InlinedRoot(_) => true,
|
DefPathData::CrateRoot | DefPathData::InlinedRoot(_) => true,
|
||||||
@ -295,21 +360,18 @@ impl Definitions {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
while self.key_map.contains_key(&key) {
|
while self.table.contains_key(&key) {
|
||||||
key.disambiguated_data.disambiguator += 1;
|
key.disambiguated_data.disambiguator += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("create_def_with_parent: after disambiguation, key = {:?}", key);
|
debug!("create_def_with_parent: after disambiguation, key = {:?}", key);
|
||||||
|
|
||||||
// Create the definition.
|
// Create the definition.
|
||||||
let index = DefIndex::new(self.data.len());
|
let index = self.table.insert(key);
|
||||||
self.data.push(DefData { key: key.clone() });
|
debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id);
|
||||||
self.def_index_to_node.push(node_id);
|
|
||||||
debug!("create_def_with_parent: node_to_def_index[{:?}] = {:?}", node_id, index);
|
|
||||||
self.node_to_def_index.insert(node_id, index);
|
self.node_to_def_index.insert(node_id, index);
|
||||||
debug!("create_def_with_parent: key_map[{:?}] = {:?}", key, index);
|
assert_eq!(index.as_usize(), self.def_index_to_node.len());
|
||||||
self.key_map.insert(key, index);
|
self.def_index_to_node.push(node_id);
|
||||||
|
|
||||||
|
|
||||||
index
|
index
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user