mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 14:21:44 +00:00
introduce hir crate
This commit is contained in:
parent
f66e5b6e6b
commit
0e4b710af8
14 changed files with 2270 additions and 17 deletions
139
crates/ra_hir/src/lib.rs
Normal file
139
crates/ra_hir/src/lib.rs
Normal file
|
@ -0,0 +1,139 @@
|
|||
//! HIR (previsouly known as descriptors) provides a high-level OO acess to Rust
|
||||
//! code.
|
||||
//!
|
||||
//! The principal difference between HIR and syntax trees is that HIR is bound
|
||||
//! to a particular crate instance. That is, it has cfg flags and features
|
||||
//! applied. So, there relation between syntax and HIR is many-to-one.
|
||||
|
||||
macro_rules! ctry {
|
||||
($expr:expr) => {
|
||||
match $expr {
|
||||
None => return Ok(None),
|
||||
Some(it) => it,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) mod db;
|
||||
mod query_definitions;
|
||||
mod function;
|
||||
mod module;
|
||||
mod path;
|
||||
mod arena;
|
||||
|
||||
use std::ops::Index;
|
||||
|
||||
use ra_syntax::{SyntaxNodeRef, SyntaxNode};
|
||||
use ra_db::{LocationIntener, SourceRootId, FileId, Cancelable};
|
||||
|
||||
use crate::{
|
||||
db::HirDatabase,
|
||||
arena::{Arena, Id},
|
||||
};
|
||||
|
||||
pub(crate) use self::{
|
||||
path::{Path, PathKind},
|
||||
module::{Module, ModuleId, Problem},
|
||||
function::{Function, FnScopes},
|
||||
};
|
||||
|
||||
pub use self::function::FnSignatureInfo;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct FnId(u32);
|
||||
ra_db::impl_numeric_id!(FnId);
|
||||
|
||||
impl FnId {
|
||||
pub(crate) fn from_loc(
|
||||
db: &impl AsRef<LocationIntener<SourceItemId, FnId>>,
|
||||
loc: &SourceItemId,
|
||||
) -> FnId {
|
||||
db.as_ref().loc2id(loc)
|
||||
}
|
||||
pub(crate) fn loc(self, db: &impl AsRef<LocationIntener<SourceItemId, FnId>>) -> SourceItemId {
|
||||
db.as_ref().id2loc(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct DefId(u32);
|
||||
ra_db::impl_numeric_id!(DefId);
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub(crate) enum DefLoc {
|
||||
Module {
|
||||
id: ModuleId,
|
||||
source_root: SourceRootId,
|
||||
},
|
||||
Item {
|
||||
source_item_id: SourceItemId,
|
||||
},
|
||||
}
|
||||
|
||||
impl DefId {
|
||||
pub(crate) fn loc(self, db: &impl AsRef<LocationIntener<DefLoc, DefId>>) -> DefLoc {
|
||||
db.as_ref().id2loc(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl DefLoc {
|
||||
pub(crate) fn id(&self, db: &impl AsRef<LocationIntener<DefLoc, DefId>>) -> DefId {
|
||||
db.as_ref().loc2id(&self)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) enum Def {
|
||||
Module(Module),
|
||||
Item,
|
||||
}
|
||||
|
||||
impl DefId {
|
||||
pub(crate) fn resolve(self, db: &impl HirDatabase) -> Cancelable<Def> {
|
||||
let loc = self.loc(db);
|
||||
let res = match loc {
|
||||
DefLoc::Module { id, source_root } => {
|
||||
let descr = Module::new(db, source_root, id)?;
|
||||
Def::Module(descr)
|
||||
}
|
||||
DefLoc::Item { .. } => Def::Item,
|
||||
};
|
||||
Ok(res)
|
||||
}
|
||||
}
|
||||
|
||||
/// Identifier of item within a specific file. This is stable over reparses, so
|
||||
/// it's OK to use it as a salsa key/value.
|
||||
pub(crate) type SourceFileItemId = Id<SyntaxNode>;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct SourceItemId {
|
||||
file_id: FileId,
|
||||
item_id: SourceFileItemId,
|
||||
}
|
||||
|
||||
/// Maps item's `SyntaxNode`s to `SourceFileItemId` and back.
|
||||
#[derive(Debug, PartialEq, Eq, Default)]
|
||||
pub(crate) struct SourceFileItems {
|
||||
arena: Arena<SyntaxNode>,
|
||||
}
|
||||
|
||||
impl SourceFileItems {
|
||||
fn alloc(&mut self, item: SyntaxNode) -> SourceFileItemId {
|
||||
self.arena.alloc(item)
|
||||
}
|
||||
fn id_of(&self, item: SyntaxNodeRef) -> SourceFileItemId {
|
||||
let (id, _item) = self
|
||||
.arena
|
||||
.iter()
|
||||
.find(|(_id, i)| i.borrowed() == item)
|
||||
.unwrap();
|
||||
id
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<SourceFileItemId> for SourceFileItems {
|
||||
type Output = SyntaxNode;
|
||||
fn index(&self, idx: SourceFileItemId) -> &SyntaxNode {
|
||||
&self.arena[idx]
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue