aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/lib.rs')
-rw-r--r--crates/ra_hir/src/lib.rs169
1 files changed, 6 insertions, 163 deletions
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index 5bbb09c01..8ee52a466 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -22,7 +22,10 @@ mod path;
22mod arena; 22mod arena;
23pub mod source_binder; 23pub mod source_binder;
24 24
25mod ids;
26mod macros;
25mod name; 27mod name;
28// can't use `crate` or `r#crate` here :(
26mod krate; 29mod krate;
27mod module; 30mod module;
28mod function; 31mod function;
@@ -30,21 +33,18 @@ mod adt;
30mod type_ref; 33mod type_ref;
31mod ty; 34mod ty;
32 35
33use std::ops::Index;
34
35use ra_syntax::{SyntaxNodeRef, SyntaxNode, SyntaxKind};
36use ra_db::{LocationIntener, SourceRootId, FileId, Cancelable};
37
38use crate::{ 36use crate::{
39 db::HirDatabase, 37 db::HirDatabase,
40 arena::{Arena, Id},
41 name::{AsName, KnownName}, 38 name::{AsName, KnownName},
39 ids::{DefKind, SourceItemId, SourceFileItemId, SourceFileItems},
42}; 40};
43 41
44pub use self::{ 42pub use self::{
45 path::{Path, PathKind}, 43 path::{Path, PathKind},
46 name::Name, 44 name::Name,
47 krate::Crate, 45 krate::Crate,
46 ids::{HirFileId, DefId, DefLoc, MacroCallId, MacroCallLoc},
47 macros::{MacroDef, MacroInput, MacroExpansion},
48 module::{Module, ModuleId, Problem, nameres::{ItemMap, PerNs, Namespace}, ModuleScope, Resolution}, 48 module::{Module, ModuleId, Problem, nameres::{ItemMap, PerNs, Namespace}, ModuleScope, Resolution},
49 function::{Function, FnScopes}, 49 function::{Function, FnScopes},
50 adt::{Struct, Enum}, 50 adt::{Struct, Enum},
@@ -53,60 +53,6 @@ pub use self::{
53 53
54pub use self::function::FnSignatureInfo; 54pub use self::function::FnSignatureInfo;
55 55
56/// Def's are a core concept of hir. A `Def` is an Item (function, module, etc)
57/// in a specific module.
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
59pub struct DefId(u32);
60ra_db::impl_numeric_id!(DefId);
61
62#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
63pub(crate) enum DefKind {
64 Module,
65 Function,
66 Struct,
67 Enum,
68 Item,
69
70 StructCtor,
71}
72
73#[derive(Clone, Debug, PartialEq, Eq, Hash)]
74pub struct DefLoc {
75 pub(crate) kind: DefKind,
76 source_root_id: SourceRootId,
77 module_id: ModuleId,
78 source_item_id: SourceItemId,
79}
80
81impl DefKind {
82 pub(crate) fn for_syntax_kind(kind: SyntaxKind) -> PerNs<DefKind> {
83 match kind {
84 SyntaxKind::FN_DEF => PerNs::values(DefKind::Function),
85 SyntaxKind::MODULE => PerNs::types(DefKind::Module),
86 SyntaxKind::STRUCT_DEF => PerNs::both(DefKind::Struct, DefKind::StructCtor),
87 SyntaxKind::ENUM_DEF => PerNs::types(DefKind::Enum),
88 // These define items, but don't have their own DefKinds yet:
89 SyntaxKind::TRAIT_DEF => PerNs::types(DefKind::Item),
90 SyntaxKind::TYPE_DEF => PerNs::types(DefKind::Item),
91 SyntaxKind::CONST_DEF => PerNs::values(DefKind::Item),
92 SyntaxKind::STATIC_DEF => PerNs::values(DefKind::Item),
93 _ => PerNs::none(),
94 }
95 }
96}
97
98impl DefId {
99 pub(crate) fn loc(self, db: &impl AsRef<LocationIntener<DefLoc, DefId>>) -> DefLoc {
100 db.as_ref().id2loc(self)
101 }
102}
103
104impl DefLoc {
105 pub(crate) fn id(&self, db: &impl AsRef<LocationIntener<DefLoc, DefId>>) -> DefId {
106 db.as_ref().loc2id(&self)
107 }
108}
109
110pub enum Def { 56pub enum Def {
111 Module(Module), 57 Module(Module),
112 Function(Function), 58 Function(Function),
@@ -114,106 +60,3 @@ pub enum Def {
114 Enum(Enum), 60 Enum(Enum),
115 Item, 61 Item,
116} 62}
117
118impl DefId {
119 pub fn resolve(self, db: &impl HirDatabase) -> Cancelable<Def> {
120 let loc = self.loc(db);
121 let res = match loc.kind {
122 DefKind::Module => {
123 let module = Module::new(db, loc.source_root_id, loc.module_id)?;
124 Def::Module(module)
125 }
126 DefKind::Function => {
127 let function = Function::new(self);
128 Def::Function(function)
129 }
130 DefKind::Struct => {
131 let struct_def = Struct::new(self);
132 Def::Struct(struct_def)
133 }
134 DefKind::Enum => {
135 let enum_def = Enum::new(self);
136 Def::Enum(enum_def)
137 }
138 DefKind::StructCtor => Def::Item,
139 DefKind::Item => Def::Item,
140 };
141 Ok(res)
142 }
143
144 /// For a module, returns that module; for any other def, returns the containing module.
145 pub fn module(self, db: &impl HirDatabase) -> Cancelable<Module> {
146 let loc = self.loc(db);
147 Module::new(db, loc.source_root_id, loc.module_id)
148 }
149}
150
151/// Identifier of item within a specific file. This is stable over reparses, so
152/// it's OK to use it as a salsa key/value.
153pub(crate) type SourceFileItemId = Id<SyntaxNode>;
154
155#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
156pub struct SourceItemId {
157 file_id: FileId,
158 /// None for the whole file.
159 item_id: Option<SourceFileItemId>,
160}
161
162/// Maps item's `SyntaxNode`s to `SourceFileItemId` and back.
163#[derive(Debug, PartialEq, Eq)]
164pub struct SourceFileItems {
165 file_id: FileId,
166 arena: Arena<SyntaxNode>,
167}
168
169impl SourceFileItems {
170 fn new(file_id: FileId) -> SourceFileItems {
171 SourceFileItems {
172 file_id,
173 arena: Arena::default(),
174 }
175 }
176
177 fn alloc(&mut self, item: SyntaxNode) -> SourceFileItemId {
178 self.arena.alloc(item)
179 }
180 pub fn id_of(&self, file_id: FileId, item: SyntaxNodeRef) -> SourceFileItemId {
181 assert_eq!(
182 self.file_id, file_id,
183 "SourceFileItems: wrong file, expected {:?}, got {:?}",
184 self.file_id, file_id
185 );
186 self.id_of_unchecked(item)
187 }
188 fn id_of_unchecked(&self, item: SyntaxNodeRef) -> SourceFileItemId {
189 if let Some((id, _)) = self.arena.iter().find(|(_id, i)| i.borrowed() == item) {
190 return id;
191 }
192 // This should not happen. Let's try to give a sensible diagnostics.
193 if let Some((id, i)) = self.arena.iter().find(|(_id, i)| i.range() == item.range()) {
194 // FIXME(#288): whyyy are we getting here?
195 log::error!(
196 "unequal syntax nodes with the same range:\n{:?}\n{:?}",
197 item,
198 i
199 );
200 return id;
201 }
202 panic!(
203 "Can't find {:?} in SourceFileItems:\n{:?}",
204 item,
205 self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(),
206 );
207 }
208 pub fn id_of_source_file(&self) -> SourceFileItemId {
209 let (id, _syntax) = self.arena.iter().next().unwrap();
210 id
211 }
212}
213
214impl Index<SourceFileItemId> for SourceFileItems {
215 type Output = SyntaxNode;
216 fn index(&self, idx: SourceFileItemId) -> &SyntaxNode {
217 &self.arena[idx]
218 }
219}