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