diff options
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/code_model_impl/module.rs | 18 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir/src/ids.rs | 75 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 69 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 69 | ||||
-rw-r--r-- | crates/ra_hir/src/source_binder.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir/src/source_id.rs | 157 |
10 files changed, 231 insertions, 207 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index 88c13566c..624c25c4d 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -13,7 +13,7 @@ use crate::{ | |||
13 | adt::{EnumVariantId, StructFieldId, VariantDef}, | 13 | adt::{EnumVariantId, StructFieldId, VariantDef}, |
14 | generics::GenericParams, | 14 | generics::GenericParams, |
15 | docs::{Documentation, Docs, docs_from_ast}, | 15 | docs::{Documentation, Docs, docs_from_ast}, |
16 | ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeId}, | 16 | ids::{FunctionId, StructId, EnumId, AstItemDef, ConstId, StaticId, TraitId, TypeAliasId}, |
17 | impl_block::ImplBlock, | 17 | impl_block::ImplBlock, |
18 | resolve::Resolver, | 18 | resolve::Resolver, |
19 | diagnostics::DiagnosticSink, | 19 | diagnostics::DiagnosticSink, |
@@ -672,7 +672,7 @@ impl Docs for Trait { | |||
672 | 672 | ||
673 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 673 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
674 | pub struct TypeAlias { | 674 | pub struct TypeAlias { |
675 | pub(crate) id: TypeId, | 675 | pub(crate) id: TypeAliasId, |
676 | } | 676 | } |
677 | 677 | ||
678 | impl TypeAlias { | 678 | impl TypeAlias { |
diff --git a/crates/ra_hir/src/code_model_impl/module.rs b/crates/ra_hir/src/code_model_impl/module.rs index 790e2b80f..0edb8ade5 100644 --- a/crates/ra_hir/src/code_model_impl/module.rs +++ b/crates/ra_hir/src/code_model_impl/module.rs | |||
@@ -1,18 +1,18 @@ | |||
1 | use ra_db::FileId; | 1 | use ra_db::FileId; |
2 | use ra_syntax::{ast, TreeArc, AstNode}; | 2 | use ra_syntax::{ast, TreeArc}; |
3 | 3 | ||
4 | use crate::{ | 4 | use crate::{ |
5 | Module, ModuleSource, Name, | 5 | Module, ModuleSource, Name, AstId, |
6 | nameres::{CrateModuleId, ImportId}, | 6 | nameres::{CrateModuleId, ImportId}, |
7 | HirDatabase, DefDatabase, | 7 | HirDatabase, DefDatabase, |
8 | HirFileId, SourceItemId, | 8 | HirFileId, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | impl ModuleSource { | 11 | impl ModuleSource { |
12 | pub(crate) fn new( | 12 | pub(crate) fn new( |
13 | db: &impl DefDatabase, | 13 | db: &impl DefDatabase, |
14 | file_id: Option<FileId>, | 14 | file_id: Option<FileId>, |
15 | decl_id: Option<SourceItemId>, | 15 | decl_id: Option<AstId<ast::Module>>, |
16 | ) -> ModuleSource { | 16 | ) -> ModuleSource { |
17 | match (file_id, decl_id) { | 17 | match (file_id, decl_id) { |
18 | (Some(file_id), _) => { | 18 | (Some(file_id), _) => { |
@@ -20,8 +20,7 @@ impl ModuleSource { | |||
20 | ModuleSource::SourceFile(source_file) | 20 | ModuleSource::SourceFile(source_file) |
21 | } | 21 | } |
22 | (None, Some(item_id)) => { | 22 | (None, Some(item_id)) => { |
23 | let module = db.file_item(item_id); | 23 | let module = item_id.to_node(db); |
24 | let module = ast::Module::cast(&*module).unwrap(); | ||
25 | assert!(module.item_list().is_some(), "expected inline module"); | 24 | assert!(module.item_list().is_some(), "expected inline module"); |
26 | ModuleSource::Module(module.to_owned()) | 25 | ModuleSource::Module(module.to_owned()) |
27 | } | 26 | } |
@@ -55,7 +54,7 @@ impl Module { | |||
55 | let decl_id = def_map[self.module_id].declaration; | 54 | let decl_id = def_map[self.module_id].declaration; |
56 | let file_id = def_map[self.module_id].definition; | 55 | let file_id = def_map[self.module_id].definition; |
57 | let module_source = ModuleSource::new(db, file_id, decl_id); | 56 | let module_source = ModuleSource::new(db, file_id, decl_id); |
58 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id); | 57 | let file_id = file_id.map(HirFileId::from).unwrap_or_else(|| decl_id.unwrap().file_id()); |
59 | (file_id, module_source) | 58 | (file_id, module_source) |
60 | } | 59 | } |
61 | 60 | ||
@@ -65,9 +64,8 @@ impl Module { | |||
65 | ) -> Option<(HirFileId, TreeArc<ast::Module>)> { | 64 | ) -> Option<(HirFileId, TreeArc<ast::Module>)> { |
66 | let def_map = db.crate_def_map(self.krate); | 65 | let def_map = db.crate_def_map(self.krate); |
67 | let decl = def_map[self.module_id].declaration?; | 66 | let decl = def_map[self.module_id].declaration?; |
68 | let syntax_node = db.file_item(decl); | 67 | let ast = decl.to_node(db); |
69 | let ast = ast::Module::cast(&syntax_node).unwrap().to_owned(); | 68 | Some((decl.file_id(), ast)) |
70 | Some((decl.file_id, ast)) | ||
71 | } | 69 | } |
72 | 70 | ||
73 | pub(crate) fn import_source_impl( | 71 | pub(crate) fn import_source_impl( |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 3296b9b31..147005848 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -4,7 +4,7 @@ use ra_syntax::{SyntaxNode, TreeArc, SourceFile}; | |||
4 | use ra_db::{SourceDatabase, salsa}; | 4 | use ra_db::{SourceDatabase, salsa}; |
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | HirFileId, MacroDefId, SourceFileItems, SourceItemId, Crate, Module, HirInterner, | 7 | HirFileId, MacroDefId, AstIdMap, ErasedFileAstId, Crate, Module, HirInterner, |
8 | Function, FnSignature, ExprScopes, TypeAlias, | 8 | Function, FnSignature, ExprScopes, TypeAlias, |
9 | Struct, Enum, StructField, | 9 | Struct, Enum, StructField, |
10 | Const, ConstSignature, Static, | 10 | Const, ConstSignature, Static, |
@@ -22,7 +22,7 @@ pub trait DefDatabase: SourceDatabase + AsRef<HirInterner> { | |||
22 | #[salsa::invoke(crate::ids::macro_def_query)] | 22 | #[salsa::invoke(crate::ids::macro_def_query)] |
23 | fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; | 23 | fn macro_def(&self, macro_id: MacroDefId) -> Option<Arc<mbe::MacroRules>>; |
24 | 24 | ||
25 | #[salsa::invoke(HirFileId::hir_parse)] | 25 | #[salsa::invoke(HirFileId::hir_parse_query)] |
26 | fn hir_parse(&self, file_id: HirFileId) -> TreeArc<SourceFile>; | 26 | fn hir_parse(&self, file_id: HirFileId) -> TreeArc<SourceFile>; |
27 | 27 | ||
28 | #[salsa::invoke(crate::adt::StructData::struct_data_query)] | 28 | #[salsa::invoke(crate::adt::StructData::struct_data_query)] |
@@ -34,11 +34,11 @@ pub trait DefDatabase: SourceDatabase + AsRef<HirInterner> { | |||
34 | #[salsa::invoke(crate::traits::TraitData::trait_data_query)] | 34 | #[salsa::invoke(crate::traits::TraitData::trait_data_query)] |
35 | fn trait_data(&self, t: Trait) -> Arc<TraitData>; | 35 | fn trait_data(&self, t: Trait) -> Arc<TraitData>; |
36 | 36 | ||
37 | #[salsa::invoke(crate::source_id::SourceFileItems::file_items_query)] | 37 | #[salsa::invoke(crate::source_id::AstIdMap::ast_id_map_query)] |
38 | fn file_items(&self, file_id: HirFileId) -> Arc<SourceFileItems>; | 38 | fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>; |
39 | 39 | ||
40 | #[salsa::invoke(crate::source_id::SourceFileItems::file_item_query)] | 40 | #[salsa::invoke(crate::source_id::AstIdMap::file_item_query)] |
41 | fn file_item(&self, source_item_id: SourceItemId) -> TreeArc<SyntaxNode>; | 41 | fn ast_id_to_node(&self, file_id: HirFileId, ast_id: ErasedFileAstId) -> TreeArc<SyntaxNode>; |
42 | 42 | ||
43 | #[salsa::invoke(RawItems::raw_items_query)] | 43 | #[salsa::invoke(RawItems::raw_items_query)] |
44 | fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; | 44 | fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; |
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs index e73dd5d21..eb9939df7 100644 --- a/crates/ra_hir/src/ids.rs +++ b/crates/ra_hir/src/ids.rs | |||
@@ -1,5 +1,4 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | marker::PhantomData, | ||
3 | hash::{Hash, Hasher}, | 2 | hash::{Hash, Hasher}, |
4 | sync::Arc, | 3 | sync::Arc, |
5 | }; | 4 | }; |
@@ -10,7 +9,7 @@ use ra_arena::{RawId, ArenaId, impl_arena_id}; | |||
10 | use mbe::MacroRules; | 9 | use mbe::MacroRules; |
11 | 10 | ||
12 | use crate::{ | 11 | use crate::{ |
13 | Module, DefDatabase, SourceItemId, SourceFileItemId, | 12 | Module, DefDatabase, AstId, FileAstId, |
14 | }; | 13 | }; |
15 | 14 | ||
16 | #[derive(Debug, Default)] | 15 | #[derive(Debug, Default)] |
@@ -22,7 +21,7 @@ pub struct HirInterner { | |||
22 | consts: LocationInterner<ItemLoc<ast::ConstDef>, ConstId>, | 21 | consts: LocationInterner<ItemLoc<ast::ConstDef>, ConstId>, |
23 | statics: LocationInterner<ItemLoc<ast::StaticDef>, StaticId>, | 22 | statics: LocationInterner<ItemLoc<ast::StaticDef>, StaticId>, |
24 | traits: LocationInterner<ItemLoc<ast::TraitDef>, TraitId>, | 23 | traits: LocationInterner<ItemLoc<ast::TraitDef>, TraitId>, |
25 | types: LocationInterner<ItemLoc<ast::TypeAliasDef>, TypeId>, | 24 | types: LocationInterner<ItemLoc<ast::TypeAliasDef>, TypeAliasId>, |
26 | } | 25 | } |
27 | 26 | ||
28 | impl HirInterner { | 27 | impl HirInterner { |
@@ -68,7 +67,7 @@ impl HirFileId { | |||
68 | HirFileIdRepr::File(file_id) => file_id, | 67 | HirFileIdRepr::File(file_id) => file_id, |
69 | HirFileIdRepr::Macro(macro_call_id) => { | 68 | HirFileIdRepr::Macro(macro_call_id) => { |
70 | let loc = macro_call_id.loc(db); | 69 | let loc = macro_call_id.loc(db); |
71 | loc.source_item_id.file_id.original_file(db) | 70 | loc.ast_id.file_id().original_file(db) |
72 | } | 71 | } |
73 | } | 72 | } |
74 | } | 73 | } |
@@ -83,7 +82,10 @@ impl HirFileId { | |||
83 | } | 82 | } |
84 | } | 83 | } |
85 | 84 | ||
86 | pub(crate) fn hir_parse(db: &impl DefDatabase, file_id: HirFileId) -> TreeArc<SourceFile> { | 85 | pub(crate) fn hir_parse_query( |
86 | db: &impl DefDatabase, | ||
87 | file_id: HirFileId, | ||
88 | ) -> TreeArc<SourceFile> { | ||
87 | match file_id.0 { | 89 | match file_id.0 { |
88 | HirFileIdRepr::File(file_id) => db.parse(file_id), | 90 | HirFileIdRepr::File(file_id) => db.parse(file_id), |
89 | HirFileIdRepr::Macro(macro_call_id) => { | 91 | HirFileIdRepr::Macro(macro_call_id) => { |
@@ -96,8 +98,7 @@ impl HirFileId { | |||
96 | 98 | ||
97 | fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<TreeArc<SourceFile>> { | 99 | fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<TreeArc<SourceFile>> { |
98 | let loc = macro_call_id.loc(db); | 100 | let loc = macro_call_id.loc(db); |
99 | let syntax = db.file_item(loc.source_item_id); | 101 | let macro_call = loc.ast_id.to_node(db); |
100 | let macro_call = ast::MacroCall::cast(&syntax).unwrap(); | ||
101 | let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?; | 102 | let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?; |
102 | 103 | ||
103 | let macro_rules = db.macro_def(loc.def)?; | 104 | let macro_rules = db.macro_def(loc.def)?; |
@@ -124,15 +125,10 @@ impl From<MacroCallId> for HirFileId { | |||
124 | } | 125 | } |
125 | 126 | ||
126 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 127 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
127 | pub enum MacroDefId { | 128 | pub struct MacroDefId(pub(crate) AstId<ast::MacroCall>); |
128 | MacroByExample { source_item_id: SourceItemId }, | ||
129 | } | ||
130 | 129 | ||
131 | pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> { | 130 | pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<Arc<MacroRules>> { |
132 | let syntax_node = match id { | 131 | let macro_call = id.0.to_node(db); |
133 | MacroDefId::MacroByExample { source_item_id } => db.file_item(source_item_id), | ||
134 | }; | ||
135 | let macro_call = ast::MacroCall::cast(&syntax_node).unwrap(); | ||
136 | let arg = macro_call.token_tree()?; | 132 | let arg = macro_call.token_tree()?; |
137 | let (tt, _) = mbe::ast_to_token_tree(arg)?; | 133 | let (tt, _) = mbe::ast_to_token_tree(arg)?; |
138 | let rules = MacroRules::parse(&tt).ok()?; | 134 | let rules = MacroRules::parse(&tt).ok()?; |
@@ -148,7 +144,7 @@ impl_arena_id!(MacroCallId); | |||
148 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 144 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
149 | pub struct MacroCallLoc { | 145 | pub struct MacroCallLoc { |
150 | pub(crate) def: MacroDefId, | 146 | pub(crate) def: MacroDefId, |
151 | pub(crate) source_item_id: SourceItemId, | 147 | pub(crate) ast_id: AstId<ast::MacroCall>, |
152 | } | 148 | } |
153 | 149 | ||
154 | impl MacroCallId { | 150 | impl MacroCallId { |
@@ -158,7 +154,6 @@ impl MacroCallId { | |||
158 | } | 154 | } |
159 | 155 | ||
160 | impl MacroCallLoc { | 156 | impl MacroCallLoc { |
161 | #[allow(unused)] | ||
162 | pub(crate) fn id(&self, db: &impl AsRef<HirInterner>) -> MacroCallId { | 157 | pub(crate) fn id(&self, db: &impl AsRef<HirInterner>) -> MacroCallId { |
163 | db.as_ref().macros.loc2id(&self) | 158 | db.as_ref().macros.loc2id(&self) |
164 | } | 159 | } |
@@ -167,26 +162,25 @@ impl MacroCallLoc { | |||
167 | #[derive(Debug)] | 162 | #[derive(Debug)] |
168 | pub struct ItemLoc<N: AstNode> { | 163 | pub struct ItemLoc<N: AstNode> { |
169 | pub(crate) module: Module, | 164 | pub(crate) module: Module, |
170 | raw: SourceItemId, | 165 | ast_id: AstId<N>, |
171 | _ty: PhantomData<N>, | ||
172 | } | 166 | } |
173 | 167 | ||
174 | impl<N: AstNode> PartialEq for ItemLoc<N> { | 168 | impl<N: AstNode> PartialEq for ItemLoc<N> { |
175 | fn eq(&self, other: &Self) -> bool { | 169 | fn eq(&self, other: &Self) -> bool { |
176 | self.module == other.module && self.raw == other.raw | 170 | self.module == other.module && self.ast_id == other.ast_id |
177 | } | 171 | } |
178 | } | 172 | } |
179 | impl<N: AstNode> Eq for ItemLoc<N> {} | 173 | impl<N: AstNode> Eq for ItemLoc<N> {} |
180 | impl<N: AstNode> Hash for ItemLoc<N> { | 174 | impl<N: AstNode> Hash for ItemLoc<N> { |
181 | fn hash<H: Hasher>(&self, hasher: &mut H) { | 175 | fn hash<H: Hasher>(&self, hasher: &mut H) { |
182 | self.module.hash(hasher); | 176 | self.module.hash(hasher); |
183 | self.raw.hash(hasher); | 177 | self.ast_id.hash(hasher); |
184 | } | 178 | } |
185 | } | 179 | } |
186 | 180 | ||
187 | impl<N: AstNode> Clone for ItemLoc<N> { | 181 | impl<N: AstNode> Clone for ItemLoc<N> { |
188 | fn clone(&self) -> ItemLoc<N> { | 182 | fn clone(&self) -> ItemLoc<N> { |
189 | ItemLoc { module: self.module, raw: self.raw, _ty: PhantomData } | 183 | ItemLoc { module: self.module, ast_id: self.ast_id } |
190 | } | 184 | } |
191 | } | 185 | } |
192 | 186 | ||
@@ -213,26 +207,19 @@ impl<'a, DB: DefDatabase> LocationCtx<&'a DB> { | |||
213 | pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | 207 | pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { |
214 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>; | 208 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<N>, Self>; |
215 | fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self { | 209 | fn from_ast(ctx: LocationCtx<&impl DefDatabase>, ast: &N) -> Self { |
216 | let items = ctx.db.file_items(ctx.file_id); | 210 | let items = ctx.db.ast_id_map(ctx.file_id); |
217 | let item_id = items.id_of(ctx.file_id, ast.syntax()); | 211 | let item_id = items.ast_id(ast); |
218 | Self::from_source_item_id_unchecked(ctx, item_id) | 212 | Self::from_ast_id(ctx, item_id) |
219 | } | 213 | } |
220 | fn from_source_item_id_unchecked( | 214 | fn from_ast_id(ctx: LocationCtx<&impl DefDatabase>, ast_id: FileAstId<N>) -> Self { |
221 | ctx: LocationCtx<&impl DefDatabase>, | 215 | let loc = ItemLoc { module: ctx.module, ast_id: ast_id.with_file_id(ctx.file_id) }; |
222 | item_id: SourceFileItemId, | ||
223 | ) -> Self { | ||
224 | let raw = SourceItemId { file_id: ctx.file_id, item_id }; | ||
225 | let loc = ItemLoc { module: ctx.module, raw, _ty: PhantomData }; | ||
226 | |||
227 | Self::interner(ctx.db.as_ref()).loc2id(&loc) | 216 | Self::interner(ctx.db.as_ref()).loc2id(&loc) |
228 | } | 217 | } |
229 | fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<N>) { | 218 | fn source(self, db: &impl DefDatabase) -> (HirFileId, TreeArc<N>) { |
230 | let int = Self::interner(db.as_ref()); | 219 | let int = Self::interner(db.as_ref()); |
231 | let loc = int.id2loc(self); | 220 | let loc = int.id2loc(self); |
232 | let syntax = db.file_item(loc.raw); | 221 | let ast = loc.ast_id.to_node(db); |
233 | let ast = | 222 | (loc.ast_id.file_id(), ast) |
234 | N::cast(&syntax).unwrap_or_else(|| panic!("invalid ItemLoc: {:?}", loc.raw)).to_owned(); | ||
235 | (loc.raw.file_id, ast) | ||
236 | } | 223 | } |
237 | fn module(self, db: &impl DefDatabase) -> Module { | 224 | fn module(self, db: &impl DefDatabase) -> Module { |
238 | let int = Self::interner(db.as_ref()); | 225 | let int = Self::interner(db.as_ref()); |
@@ -242,7 +229,7 @@ pub(crate) trait AstItemDef<N: AstNode>: ArenaId + Clone { | |||
242 | } | 229 | } |
243 | 230 | ||
244 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 231 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
245 | pub struct FunctionId(RawId); | 232 | pub(crate) struct FunctionId(RawId); |
246 | impl_arena_id!(FunctionId); | 233 | impl_arena_id!(FunctionId); |
247 | impl AstItemDef<ast::FnDef> for FunctionId { | 234 | impl AstItemDef<ast::FnDef> for FunctionId { |
248 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::FnDef>, Self> { | 235 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::FnDef>, Self> { |
@@ -251,7 +238,7 @@ impl AstItemDef<ast::FnDef> for FunctionId { | |||
251 | } | 238 | } |
252 | 239 | ||
253 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 240 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
254 | pub struct StructId(RawId); | 241 | pub(crate) struct StructId(RawId); |
255 | impl_arena_id!(StructId); | 242 | impl_arena_id!(StructId); |
256 | impl AstItemDef<ast::StructDef> for StructId { | 243 | impl AstItemDef<ast::StructDef> for StructId { |
257 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::StructDef>, Self> { | 244 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::StructDef>, Self> { |
@@ -260,7 +247,7 @@ impl AstItemDef<ast::StructDef> for StructId { | |||
260 | } | 247 | } |
261 | 248 | ||
262 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 249 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
263 | pub struct EnumId(RawId); | 250 | pub(crate) struct EnumId(RawId); |
264 | impl_arena_id!(EnumId); | 251 | impl_arena_id!(EnumId); |
265 | impl AstItemDef<ast::EnumDef> for EnumId { | 252 | impl AstItemDef<ast::EnumDef> for EnumId { |
266 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::EnumDef>, Self> { | 253 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::EnumDef>, Self> { |
@@ -269,7 +256,7 @@ impl AstItemDef<ast::EnumDef> for EnumId { | |||
269 | } | 256 | } |
270 | 257 | ||
271 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 258 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
272 | pub struct ConstId(RawId); | 259 | pub(crate) struct ConstId(RawId); |
273 | impl_arena_id!(ConstId); | 260 | impl_arena_id!(ConstId); |
274 | impl AstItemDef<ast::ConstDef> for ConstId { | 261 | impl AstItemDef<ast::ConstDef> for ConstId { |
275 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::ConstDef>, Self> { | 262 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::ConstDef>, Self> { |
@@ -278,7 +265,7 @@ impl AstItemDef<ast::ConstDef> for ConstId { | |||
278 | } | 265 | } |
279 | 266 | ||
280 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 267 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
281 | pub struct StaticId(RawId); | 268 | pub(crate) struct StaticId(RawId); |
282 | impl_arena_id!(StaticId); | 269 | impl_arena_id!(StaticId); |
283 | impl AstItemDef<ast::StaticDef> for StaticId { | 270 | impl AstItemDef<ast::StaticDef> for StaticId { |
284 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::StaticDef>, Self> { | 271 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::StaticDef>, Self> { |
@@ -287,7 +274,7 @@ impl AstItemDef<ast::StaticDef> for StaticId { | |||
287 | } | 274 | } |
288 | 275 | ||
289 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 276 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
290 | pub struct TraitId(RawId); | 277 | pub(crate) struct TraitId(RawId); |
291 | impl_arena_id!(TraitId); | 278 | impl_arena_id!(TraitId); |
292 | impl AstItemDef<ast::TraitDef> for TraitId { | 279 | impl AstItemDef<ast::TraitDef> for TraitId { |
293 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::TraitDef>, Self> { | 280 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::TraitDef>, Self> { |
@@ -296,9 +283,9 @@ impl AstItemDef<ast::TraitDef> for TraitId { | |||
296 | } | 283 | } |
297 | 284 | ||
298 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 285 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
299 | pub struct TypeId(RawId); | 286 | pub(crate) struct TypeAliasId(RawId); |
300 | impl_arena_id!(TypeId); | 287 | impl_arena_id!(TypeAliasId); |
301 | impl AstItemDef<ast::TypeAliasDef> for TypeId { | 288 | impl AstItemDef<ast::TypeAliasDef> for TypeAliasId { |
302 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::TypeAliasDef>, Self> { | 289 | fn interner(interner: &HirInterner) -> &LocationInterner<ItemLoc<ast::TypeAliasDef>, Self> { |
303 | &interner.types | 290 | &interner.types |
304 | } | 291 | } |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index ac2585de0..7c603bbd3 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -48,13 +48,13 @@ mod marks; | |||
48 | use crate::{ | 48 | use crate::{ |
49 | db::{HirDatabase, DefDatabase}, | 49 | db::{HirDatabase, DefDatabase}, |
50 | name::{AsName, KnownName}, | 50 | name::{AsName, KnownName}, |
51 | source_id::SourceFileItemId, | 51 | source_id::{FileAstId, AstId}, |
52 | }; | 52 | }; |
53 | 53 | ||
54 | pub use self::{ | 54 | pub use self::{ |
55 | path::{Path, PathKind}, | 55 | path::{Path, PathKind}, |
56 | name::Name, | 56 | name::Name, |
57 | source_id::{SourceFileItems, SourceItemId}, | 57 | source_id::{AstIdMap, ErasedFileAstId}, |
58 | ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, HirInterner}, | 58 | ids::{HirFileId, MacroDefId, MacroCallId, MacroCallLoc, HirInterner}, |
59 | nameres::{PerNs, Namespace}, | 59 | nameres::{PerNs, Namespace}, |
60 | ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay}, | 60 | ty::{Ty, ApplicationTy, TypeCtor, Substs, display::HirDisplay}, |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index e962bbd31..67b9d6986 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -59,13 +59,15 @@ use rustc_hash::FxHashMap; | |||
59 | use ra_arena::{Arena, RawId, impl_arena_id}; | 59 | use ra_arena::{Arena, RawId, impl_arena_id}; |
60 | use ra_db::{FileId, Edition}; | 60 | use ra_db::{FileId, Edition}; |
61 | use test_utils::tested_by; | 61 | use test_utils::tested_by; |
62 | use ra_syntax::ast; | ||
62 | 63 | ||
63 | use crate::{ | 64 | use crate::{ |
64 | ModuleDef, Name, Crate, Module, SourceItemId, | 65 | ModuleDef, Name, Crate, Module, |
65 | DefDatabase, Path, PathKind, HirFileId, Trait, | 66 | DefDatabase, Path, PathKind, HirFileId, Trait, |
66 | ids::MacroDefId, | 67 | ids::MacroDefId, |
67 | diagnostics::DiagnosticSink, | 68 | diagnostics::DiagnosticSink, |
68 | nameres::diagnostics::DefDiagnostic, | 69 | nameres::diagnostics::DefDiagnostic, |
70 | AstId, | ||
69 | }; | 71 | }; |
70 | 72 | ||
71 | pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; | 73 | pub(crate) use self::raw::{RawItems, ImportId, ImportSourceMap}; |
@@ -106,7 +108,7 @@ pub(crate) struct ModuleData { | |||
106 | pub(crate) children: FxHashMap<Name, CrateModuleId>, | 108 | pub(crate) children: FxHashMap<Name, CrateModuleId>, |
107 | pub(crate) scope: ModuleScope, | 109 | pub(crate) scope: ModuleScope, |
108 | /// None for root | 110 | /// None for root |
109 | pub(crate) declaration: Option<SourceItemId>, | 111 | pub(crate) declaration: Option<AstId<ast::Module>>, |
110 | /// None for inline modules. | 112 | /// None for inline modules. |
111 | /// | 113 | /// |
112 | /// Note that non-inline modules, by definition, live inside non-macro file. | 114 | /// Note that non-inline modules, by definition, live inside non-macro file. |
@@ -225,7 +227,7 @@ impl CrateDefMap { | |||
225 | pub(crate) fn find_module_by_source( | 227 | pub(crate) fn find_module_by_source( |
226 | &self, | 228 | &self, |
227 | file_id: HirFileId, | 229 | file_id: HirFileId, |
228 | decl_id: Option<SourceItemId>, | 230 | decl_id: Option<AstId<ast::Module>>, |
229 | ) -> Option<CrateModuleId> { | 231 | ) -> Option<CrateModuleId> { |
230 | let (module_id, _module_data) = self.modules.iter().find(|(_module_id, module_data)| { | 232 | let (module_id, _module_data) = self.modules.iter().find(|(_module_id, module_data)| { |
231 | if decl_id.is_some() { | 233 | if decl_id.is_some() { |
@@ -429,10 +431,10 @@ impl CrateDefMap { | |||
429 | 431 | ||
430 | mod diagnostics { | 432 | mod diagnostics { |
431 | use relative_path::RelativePathBuf; | 433 | use relative_path::RelativePathBuf; |
432 | use ra_syntax::{AstPtr, AstNode, ast}; | 434 | use ra_syntax::{AstPtr, ast}; |
433 | 435 | ||
434 | use crate::{ | 436 | use crate::{ |
435 | SourceItemId, DefDatabase, | 437 | AstId, DefDatabase, |
436 | nameres::CrateModuleId, | 438 | nameres::CrateModuleId, |
437 | diagnostics::{DiagnosticSink, UnresolvedModule}, | 439 | diagnostics::{DiagnosticSink, UnresolvedModule}, |
438 | }; | 440 | }; |
@@ -441,7 +443,7 @@ mod diagnostics { | |||
441 | pub(super) enum DefDiagnostic { | 443 | pub(super) enum DefDiagnostic { |
442 | UnresolvedModule { | 444 | UnresolvedModule { |
443 | module: CrateModuleId, | 445 | module: CrateModuleId, |
444 | declaration: SourceItemId, | 446 | declaration: AstId<ast::Module>, |
445 | candidate: RelativePathBuf, | 447 | candidate: RelativePathBuf, |
446 | }, | 448 | }, |
447 | } | 449 | } |
@@ -458,10 +460,9 @@ mod diagnostics { | |||
458 | if *module != target_module { | 460 | if *module != target_module { |
459 | return; | 461 | return; |
460 | } | 462 | } |
461 | let syntax = db.file_item(*declaration); | 463 | let decl = declaration.to_node(db); |
462 | let decl = ast::Module::cast(&syntax).unwrap(); | ||
463 | sink.push(UnresolvedModule { | 464 | sink.push(UnresolvedModule { |
464 | file: declaration.file_id, | 465 | file: declaration.file_id(), |
465 | decl: AstPtr::new(&decl), | 466 | decl: AstPtr::new(&decl), |
466 | candidate: candidate.clone(), | 467 | candidate: candidate.clone(), |
467 | }) | 468 | }) |
@@ -469,5 +470,4 @@ mod diagnostics { | |||
469 | } | 470 | } |
470 | } | 471 | } |
471 | } | 472 | } |
472 | |||
473 | } | 473 | } |
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 4fb298155..39cadc94a 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -3,10 +3,11 @@ use rustc_hash::FxHashMap; | |||
3 | use relative_path::RelativePathBuf; | 3 | use relative_path::RelativePathBuf; |
4 | use test_utils::tested_by; | 4 | use test_utils::tested_by; |
5 | use ra_db::FileId; | 5 | use ra_db::FileId; |
6 | use ra_syntax::ast; | ||
6 | 7 | ||
7 | use crate::{ | 8 | use crate::{ |
8 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, | 9 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, |
9 | DefDatabase, HirFileId, Name, Path, SourceItemId, | 10 | DefDatabase, HirFileId, Name, Path, |
10 | KnownName, | 11 | KnownName, |
11 | nameres::{ | 12 | nameres::{ |
12 | Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, | 13 | Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, |
@@ -15,6 +16,7 @@ use crate::{ | |||
15 | raw, | 16 | raw, |
16 | }, | 17 | }, |
17 | ids::{AstItemDef, LocationCtx, MacroCallLoc, MacroCallId, MacroDefId}, | 18 | ids::{AstItemDef, LocationCtx, MacroCallLoc, MacroCallId, MacroDefId}, |
19 | AstId, | ||
18 | }; | 20 | }; |
19 | 21 | ||
20 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 22 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { |
@@ -51,7 +53,7 @@ struct DefCollector<DB> { | |||
51 | def_map: CrateDefMap, | 53 | def_map: CrateDefMap, |
52 | glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, | 54 | glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, |
53 | unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, | 55 | unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, |
54 | unexpanded_macros: Vec<(CrateModuleId, SourceItemId, Path)>, | 56 | unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>, |
55 | global_macro_scope: FxHashMap<Name, MacroDefId>, | 57 | global_macro_scope: FxHashMap<Name, MacroDefId>, |
56 | } | 58 | } |
57 | 59 | ||
@@ -293,7 +295,7 @@ where | |||
293 | let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); | 295 | let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); |
294 | let mut resolved = Vec::new(); | 296 | let mut resolved = Vec::new(); |
295 | let mut res = ReachedFixedPoint::Yes; | 297 | let mut res = ReachedFixedPoint::Yes; |
296 | macros.retain(|(module_id, source_item_id, path)| { | 298 | macros.retain(|(module_id, ast_id, path)| { |
297 | if path.segments.len() != 2 { | 299 | if path.segments.len() != 2 { |
298 | return true; | 300 | return true; |
299 | } | 301 | } |
@@ -309,8 +311,7 @@ where | |||
309 | res = ReachedFixedPoint::No; | 311 | res = ReachedFixedPoint::No; |
310 | let def_map = self.db.crate_def_map(krate); | 312 | let def_map = self.db.crate_def_map(krate); |
311 | if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() { | 313 | if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() { |
312 | let call_id = | 314 | let call_id = MacroCallLoc { def: macro_id, ast_id: *ast_id }.id(self.db); |
313 | MacroCallLoc { def: macro_id, source_item_id: *source_item_id }.id(self.db); | ||
314 | resolved.push((*module_id, call_id)); | 315 | resolved.push((*module_id, call_id)); |
315 | } | 316 | } |
316 | false | 317 | false |
@@ -364,12 +365,9 @@ where | |||
364 | fn collect_module(&mut self, module: &raw::ModuleData) { | 365 | fn collect_module(&mut self, module: &raw::ModuleData) { |
365 | match module { | 366 | match module { |
366 | // inline module, just recurse | 367 | // inline module, just recurse |
367 | raw::ModuleData::Definition { name, items, source_item_id } => { | 368 | raw::ModuleData::Definition { name, items, ast_id } => { |
368 | let module_id = self.push_child_module( | 369 | let module_id = |
369 | name.clone(), | 370 | self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); |
370 | source_item_id.with_file_id(self.file_id), | ||
371 | None, | ||
372 | ); | ||
373 | ModCollector { | 371 | ModCollector { |
374 | def_collector: &mut *self.def_collector, | 372 | def_collector: &mut *self.def_collector, |
375 | module_id, | 373 | module_id, |
@@ -379,13 +377,12 @@ where | |||
379 | .collect(&*items); | 377 | .collect(&*items); |
380 | } | 378 | } |
381 | // out of line module, resovle, parse and recurse | 379 | // out of line module, resovle, parse and recurse |
382 | raw::ModuleData::Declaration { name, source_item_id } => { | 380 | raw::ModuleData::Declaration { name, ast_id } => { |
383 | let source_item_id = source_item_id.with_file_id(self.file_id); | 381 | let ast_id = ast_id.with_file_id(self.file_id); |
384 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); | 382 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); |
385 | match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) { | 383 | match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) { |
386 | Ok(file_id) => { | 384 | Ok(file_id) => { |
387 | let module_id = | 385 | let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); |
388 | self.push_child_module(name.clone(), source_item_id, Some(file_id)); | ||
389 | let raw_items = self.def_collector.db.raw_items(file_id.into()); | 386 | let raw_items = self.def_collector.db.raw_items(file_id.into()); |
390 | ModCollector { | 387 | ModCollector { |
391 | def_collector: &mut *self.def_collector, | 388 | def_collector: &mut *self.def_collector, |
@@ -398,7 +395,7 @@ where | |||
398 | Err(candidate) => self.def_collector.def_map.diagnostics.push( | 395 | Err(candidate) => self.def_collector.def_map.diagnostics.push( |
399 | DefDiagnostic::UnresolvedModule { | 396 | DefDiagnostic::UnresolvedModule { |
400 | module: self.module_id, | 397 | module: self.module_id, |
401 | declaration: source_item_id, | 398 | declaration: ast_id, |
402 | candidate, | 399 | candidate, |
403 | }, | 400 | }, |
404 | ), | 401 | ), |
@@ -410,7 +407,7 @@ where | |||
410 | fn push_child_module( | 407 | fn push_child_module( |
411 | &mut self, | 408 | &mut self, |
412 | name: Name, | 409 | name: Name, |
413 | declaration: SourceItemId, | 410 | declaration: AstId<ast::Module>, |
414 | definition: Option<FileId>, | 411 | definition: Option<FileId>, |
415 | ) -> CrateModuleId { | 412 | ) -> CrateModuleId { |
416 | let modules = &mut self.def_collector.def_map.modules; | 413 | let modules = &mut self.def_collector.def_map.modules; |
@@ -432,23 +429,24 @@ where | |||
432 | fn define_def(&mut self, def: &raw::DefData) { | 429 | fn define_def(&mut self, def: &raw::DefData) { |
433 | let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }; | 430 | let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }; |
434 | let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id.into()); | 431 | let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id.into()); |
435 | macro_rules! id { | 432 | |
436 | () => { | 433 | macro_rules! def { |
437 | AstItemDef::from_source_item_id_unchecked(ctx, def.source_item_id) | 434 | ($kind:ident, $ast_id:ident) => { |
435 | $kind { id: AstItemDef::from_ast_id(ctx, $ast_id) }.into() | ||
438 | }; | 436 | }; |
439 | } | 437 | } |
440 | let name = def.name.clone(); | 438 | let name = def.name.clone(); |
441 | let def: PerNs<ModuleDef> = match def.kind { | 439 | let def: PerNs<ModuleDef> = match def.kind { |
442 | raw::DefKind::Function => PerNs::values(Function { id: id!() }.into()), | 440 | raw::DefKind::Function(ast_id) => PerNs::values(def!(Function, ast_id)), |
443 | raw::DefKind::Struct => { | 441 | raw::DefKind::Struct(ast_id) => { |
444 | let s = Struct { id: id!() }.into(); | 442 | let s = def!(Struct, ast_id); |
445 | PerNs::both(s, s) | 443 | PerNs::both(s, s) |
446 | } | 444 | } |
447 | raw::DefKind::Enum => PerNs::types(Enum { id: id!() }.into()), | 445 | raw::DefKind::Enum(ast_id) => PerNs::types(def!(Enum, ast_id)), |
448 | raw::DefKind::Const => PerNs::values(Const { id: id!() }.into()), | 446 | raw::DefKind::Const(ast_id) => PerNs::values(def!(Const, ast_id)), |
449 | raw::DefKind::Static => PerNs::values(Static { id: id!() }.into()), | 447 | raw::DefKind::Static(ast_id) => PerNs::values(def!(Static, ast_id)), |
450 | raw::DefKind::Trait => PerNs::types(Trait { id: id!() }.into()), | 448 | raw::DefKind::Trait(ast_id) => PerNs::types(def!(Trait, ast_id)), |
451 | raw::DefKind::TypeAlias => PerNs::types(TypeAlias { id: id!() }.into()), | 449 | raw::DefKind::TypeAlias(ast_id) => PerNs::types(def!(TypeAlias, ast_id)), |
452 | }; | 450 | }; |
453 | let resolution = Resolution { def, import: None }; | 451 | let resolution = Resolution { def, import: None }; |
454 | self.def_collector.update(self.module_id, None, &[(name, resolution)]) | 452 | self.def_collector.update(self.module_id, None, &[(name, resolution)]) |
@@ -458,34 +456,27 @@ where | |||
458 | // Case 1: macro rules, define a macro in crate-global mutable scope | 456 | // Case 1: macro rules, define a macro in crate-global mutable scope |
459 | if is_macro_rules(&mac.path) { | 457 | if is_macro_rules(&mac.path) { |
460 | if let Some(name) = &mac.name { | 458 | if let Some(name) = &mac.name { |
461 | let macro_id = MacroDefId::MacroByExample { | 459 | let macro_id = MacroDefId(mac.ast_id.with_file_id(self.file_id)); |
462 | source_item_id: mac.source_item_id.with_file_id(self.file_id), | ||
463 | }; | ||
464 | self.def_collector.define_macro(name.clone(), macro_id, mac.export) | 460 | self.def_collector.define_macro(name.clone(), macro_id, mac.export) |
465 | } | 461 | } |
466 | return; | 462 | return; |
467 | } | 463 | } |
468 | 464 | ||
469 | let source_item_id = SourceItemId { file_id: self.file_id, item_id: mac.source_item_id }; | 465 | let ast_id = mac.ast_id.with_file_id(self.file_id); |
470 | 466 | ||
471 | // Case 2: try to expand macro_rules from this crate, triggering | 467 | // Case 2: try to expand macro_rules from this crate, triggering |
472 | // recursive item collection. | 468 | // recursive item collection. |
473 | if let Some(¯o_id) = | 469 | if let Some(¯o_id) = |
474 | mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) | 470 | mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) |
475 | { | 471 | { |
476 | let macro_call_id = | 472 | let macro_call_id = MacroCallLoc { def: macro_id, ast_id }.id(self.def_collector.db); |
477 | MacroCallLoc { def: macro_id, source_item_id }.id(self.def_collector.db); | ||
478 | 473 | ||
479 | self.def_collector.collect_macro_expansion(self.module_id, macro_call_id); | 474 | self.def_collector.collect_macro_expansion(self.module_id, macro_call_id); |
480 | return; | 475 | return; |
481 | } | 476 | } |
482 | 477 | ||
483 | // Case 3: path to a macro from another crate, expand during name resolution | 478 | // Case 3: path to a macro from another crate, expand during name resolution |
484 | self.def_collector.unexpanded_macros.push(( | 479 | self.def_collector.unexpanded_macros.push((self.module_id, ast_id, mac.path.clone())) |
485 | self.module_id, | ||
486 | source_item_id, | ||
487 | mac.path.clone(), | ||
488 | )) | ||
489 | } | 480 | } |
490 | } | 481 | } |
491 | 482 | ||
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index f32004601..0936229ac 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -12,7 +12,7 @@ use ra_syntax::{ | |||
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, | 14 | DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, |
15 | SourceFileItemId, SourceFileItems, | 15 | AstIdMap, FileAstId, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | /// `RawItems` is a set of top-level items in a file (except for impls). | 18 | /// `RawItems` is a set of top-level items in a file (except for impls). |
@@ -60,7 +60,7 @@ impl RawItems { | |||
60 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { | 60 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { |
61 | let mut collector = RawItemsCollector { | 61 | let mut collector = RawItemsCollector { |
62 | raw_items: RawItems::default(), | 62 | raw_items: RawItems::default(), |
63 | source_file_items: db.file_items(file_id.into()), | 63 | source_ast_id_map: db.ast_id_map(file_id.into()), |
64 | source_map: ImportSourceMap::default(), | 64 | source_map: ImportSourceMap::default(), |
65 | }; | 65 | }; |
66 | let source_file = db.hir_parse(file_id); | 66 | let source_file = db.hir_parse(file_id); |
@@ -115,8 +115,8 @@ impl_arena_id!(Module); | |||
115 | 115 | ||
116 | #[derive(Debug, PartialEq, Eq)] | 116 | #[derive(Debug, PartialEq, Eq)] |
117 | pub(super) enum ModuleData { | 117 | pub(super) enum ModuleData { |
118 | Declaration { name: Name, source_item_id: SourceFileItemId }, | 118 | Declaration { name: Name, ast_id: FileAstId<ast::Module> }, |
119 | Definition { name: Name, source_item_id: SourceFileItemId, items: Vec<RawItem> }, | 119 | Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> }, |
120 | } | 120 | } |
121 | 121 | ||
122 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 122 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -138,20 +138,19 @@ impl_arena_id!(Def); | |||
138 | 138 | ||
139 | #[derive(Debug, PartialEq, Eq)] | 139 | #[derive(Debug, PartialEq, Eq)] |
140 | pub(super) struct DefData { | 140 | pub(super) struct DefData { |
141 | pub(super) source_item_id: SourceFileItemId, | ||
142 | pub(super) name: Name, | 141 | pub(super) name: Name, |
143 | pub(super) kind: DefKind, | 142 | pub(super) kind: DefKind, |
144 | } | 143 | } |
145 | 144 | ||
146 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 145 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
147 | pub(super) enum DefKind { | 146 | pub(super) enum DefKind { |
148 | Function, | 147 | Function(FileAstId<ast::FnDef>), |
149 | Struct, | 148 | Struct(FileAstId<ast::StructDef>), |
150 | Enum, | 149 | Enum(FileAstId<ast::EnumDef>), |
151 | Const, | 150 | Const(FileAstId<ast::ConstDef>), |
152 | Static, | 151 | Static(FileAstId<ast::StaticDef>), |
153 | Trait, | 152 | Trait(FileAstId<ast::TraitDef>), |
154 | TypeAlias, | 153 | TypeAlias(FileAstId<ast::TypeAliasDef>), |
155 | } | 154 | } |
156 | 155 | ||
157 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 156 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -160,7 +159,7 @@ impl_arena_id!(Macro); | |||
160 | 159 | ||
161 | #[derive(Debug, PartialEq, Eq)] | 160 | #[derive(Debug, PartialEq, Eq)] |
162 | pub(super) struct MacroData { | 161 | pub(super) struct MacroData { |
163 | pub(super) source_item_id: SourceFileItemId, | 162 | pub(super) ast_id: FileAstId<ast::MacroCall>, |
164 | pub(super) path: Path, | 163 | pub(super) path: Path, |
165 | pub(super) name: Option<Name>, | 164 | pub(super) name: Option<Name>, |
166 | pub(super) export: bool, | 165 | pub(super) export: bool, |
@@ -168,7 +167,7 @@ pub(super) struct MacroData { | |||
168 | 167 | ||
169 | struct RawItemsCollector { | 168 | struct RawItemsCollector { |
170 | raw_items: RawItems, | 169 | raw_items: RawItems, |
171 | source_file_items: Arc<SourceFileItems>, | 170 | source_ast_id_map: Arc<AstIdMap>, |
172 | source_map: ImportSourceMap, | 171 | source_map: ImportSourceMap, |
173 | } | 172 | } |
174 | 173 | ||
@@ -200,18 +199,31 @@ impl RawItemsCollector { | |||
200 | // impls don't participate in name resolution | 199 | // impls don't participate in name resolution |
201 | return; | 200 | return; |
202 | } | 201 | } |
203 | ast::ModuleItemKind::StructDef(it) => (DefKind::Struct, it.name()), | 202 | ast::ModuleItemKind::StructDef(it) => { |
204 | ast::ModuleItemKind::EnumDef(it) => (DefKind::Enum, it.name()), | 203 | (DefKind::Struct(self.source_ast_id_map.ast_id(it)), it.name()) |
205 | ast::ModuleItemKind::FnDef(it) => (DefKind::Function, it.name()), | 204 | } |
206 | ast::ModuleItemKind::TraitDef(it) => (DefKind::Trait, it.name()), | 205 | ast::ModuleItemKind::EnumDef(it) => { |
207 | ast::ModuleItemKind::TypeAliasDef(it) => (DefKind::TypeAlias, it.name()), | 206 | (DefKind::Enum(self.source_ast_id_map.ast_id(it)), it.name()) |
208 | ast::ModuleItemKind::ConstDef(it) => (DefKind::Const, it.name()), | 207 | } |
209 | ast::ModuleItemKind::StaticDef(it) => (DefKind::Static, it.name()), | 208 | ast::ModuleItemKind::FnDef(it) => { |
209 | (DefKind::Function(self.source_ast_id_map.ast_id(it)), it.name()) | ||
210 | } | ||
211 | ast::ModuleItemKind::TraitDef(it) => { | ||
212 | (DefKind::Trait(self.source_ast_id_map.ast_id(it)), it.name()) | ||
213 | } | ||
214 | ast::ModuleItemKind::TypeAliasDef(it) => { | ||
215 | (DefKind::TypeAlias(self.source_ast_id_map.ast_id(it)), it.name()) | ||
216 | } | ||
217 | ast::ModuleItemKind::ConstDef(it) => { | ||
218 | (DefKind::Const(self.source_ast_id_map.ast_id(it)), it.name()) | ||
219 | } | ||
220 | ast::ModuleItemKind::StaticDef(it) => { | ||
221 | (DefKind::Static(self.source_ast_id_map.ast_id(it)), it.name()) | ||
222 | } | ||
210 | }; | 223 | }; |
211 | if let Some(name) = name { | 224 | if let Some(name) = name { |
212 | let name = name.as_name(); | 225 | let name = name.as_name(); |
213 | let source_item_id = self.source_file_items.id_of_unchecked(item.syntax()); | 226 | let def = self.raw_items.defs.alloc(DefData { name, kind }); |
214 | let def = self.raw_items.defs.alloc(DefData { name, kind, source_item_id }); | ||
215 | self.push_item(current_module, RawItem::Def(def)) | 227 | self.push_item(current_module, RawItem::Def(def)) |
216 | } | 228 | } |
217 | } | 229 | } |
@@ -221,10 +233,9 @@ impl RawItemsCollector { | |||
221 | Some(it) => it.as_name(), | 233 | Some(it) => it.as_name(), |
222 | None => return, | 234 | None => return, |
223 | }; | 235 | }; |
224 | let source_item_id = self.source_file_items.id_of_unchecked(module.syntax()); | 236 | let ast_id = self.source_ast_id_map.ast_id(module); |
225 | if module.has_semi() { | 237 | if module.has_semi() { |
226 | let item = | 238 | let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id }); |
227 | self.raw_items.modules.alloc(ModuleData::Declaration { name, source_item_id }); | ||
228 | self.push_item(current_module, RawItem::Module(item)); | 239 | self.push_item(current_module, RawItem::Module(item)); |
229 | return; | 240 | return; |
230 | } | 241 | } |
@@ -232,7 +243,7 @@ impl RawItemsCollector { | |||
232 | if let Some(item_list) = module.item_list() { | 243 | if let Some(item_list) = module.item_list() { |
233 | let item = self.raw_items.modules.alloc(ModuleData::Definition { | 244 | let item = self.raw_items.modules.alloc(ModuleData::Definition { |
234 | name, | 245 | name, |
235 | source_item_id, | 246 | ast_id, |
236 | items: Vec::new(), | 247 | items: Vec::new(), |
237 | }); | 248 | }); |
238 | self.process_module(Some(item), item_list); | 249 | self.process_module(Some(item), item_list); |
@@ -286,9 +297,9 @@ impl RawItemsCollector { | |||
286 | }; | 297 | }; |
287 | 298 | ||
288 | let name = m.name().map(|it| it.as_name()); | 299 | let name = m.name().map(|it| it.as_name()); |
289 | let source_item_id = self.source_file_items.id_of_unchecked(m.syntax()); | 300 | let ast_id = self.source_ast_id_map.ast_id(m); |
290 | let export = m.has_atom_attr("macro_export"); | 301 | let export = m.has_atom_attr("macro_export"); |
291 | let m = self.raw_items.macros.alloc(MacroData { source_item_id, path, name, export }); | 302 | let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export }); |
292 | self.push_item(current_module, RawItem::Macro(m)); | 303 | self.push_item(current_module, RawItem::Macro(m)); |
293 | } | 304 | } |
294 | 305 | ||
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index db9e3a22e..9dae4c3d1 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -13,10 +13,10 @@ use ra_syntax::{ | |||
13 | }; | 13 | }; |
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | HirDatabase, Function, Struct, Enum, SourceItemId, | 16 | HirDatabase, Function, Struct, Enum, |
17 | AsName, Module, HirFileId, Crate, Trait, Resolver, | 17 | AsName, Module, HirFileId, Crate, Trait, Resolver, |
18 | ids::LocationCtx, | 18 | ids::LocationCtx, |
19 | expr | 19 | expr, AstId |
20 | }; | 20 | }; |
21 | 21 | ||
22 | /// Locates the module by `FileId`. Picks topmost module in the file. | 22 | /// Locates the module by `FileId`. Picks topmost module in the file. |
@@ -54,8 +54,8 @@ fn module_from_inline( | |||
54 | ) -> Option<Module> { | 54 | ) -> Option<Module> { |
55 | assert!(!module.has_semi()); | 55 | assert!(!module.has_semi()); |
56 | let file_id = file_id.into(); | 56 | let file_id = file_id.into(); |
57 | let file_items = db.file_items(file_id); | 57 | let ast_id_map = db.ast_id_map(file_id); |
58 | let item_id = file_items.id_of(file_id, module.syntax()).with_file_id(file_id); | 58 | let item_id = ast_id_map.ast_id(module).with_file_id(file_id); |
59 | module_from_source(db, file_id, Some(item_id)) | 59 | module_from_source(db, file_id, Some(item_id)) |
60 | } | 60 | } |
61 | 61 | ||
@@ -75,7 +75,7 @@ pub fn module_from_child_node( | |||
75 | fn module_from_source( | 75 | fn module_from_source( |
76 | db: &impl HirDatabase, | 76 | db: &impl HirDatabase, |
77 | file_id: HirFileId, | 77 | file_id: HirFileId, |
78 | decl_id: Option<SourceItemId>, | 78 | decl_id: Option<AstId<ast::Module>>, |
79 | ) -> Option<Module> { | 79 | ) -> Option<Module> { |
80 | let source_root_id = db.file_source_root(file_id.as_original_file()); | 80 | let source_root_id = db.file_source_root(file_id.as_original_file()); |
81 | db.source_root_crates(source_root_id).iter().map(|&crate_id| Crate { crate_id }).find_map( | 81 | db.source_root_crates(source_root_id).iter().map(|&crate_id| Crate { crate_id }).find_map( |
diff --git a/crates/ra_hir/src/source_id.rs b/crates/ra_hir/src/source_id.rs index 62707ba6a..0a8fb6d32 100644 --- a/crates/ra_hir/src/source_id.rs +++ b/crates/ra_hir/src/source_id.rs | |||
@@ -1,59 +1,122 @@ | |||
1 | use std::sync::Arc; | 1 | use std::{marker::PhantomData, sync::Arc, hash::{Hash, Hasher}}; |
2 | 2 | ||
3 | use ra_arena::{Arena, RawId, impl_arena_id}; | 3 | use ra_arena::{Arena, RawId, impl_arena_id}; |
4 | use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast}; | 4 | use ra_syntax::{SyntaxNodePtr, TreeArc, SyntaxNode, SourceFile, AstNode, ast}; |
5 | 5 | ||
6 | use crate::{HirFileId, DefDatabase}; | 6 | use crate::{HirFileId, DefDatabase}; |
7 | 7 | ||
8 | /// Identifier of item within a specific file. This is stable over reparses, so | 8 | /// `AstId` points to an AST node in any file. |
9 | /// it's OK to use it as a salsa key/value. | 9 | /// |
10 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | 10 | /// It is stable across reparses, and can be used as salsa key/value. |
11 | pub(crate) struct SourceFileItemId(RawId); | 11 | #[derive(Debug)] |
12 | impl_arena_id!(SourceFileItemId); | 12 | pub(crate) struct AstId<N: AstNode> { |
13 | file_id: HirFileId, | ||
14 | file_ast_id: FileAstId<N>, | ||
15 | } | ||
16 | |||
17 | impl<N: AstNode> Clone for AstId<N> { | ||
18 | fn clone(&self) -> AstId<N> { | ||
19 | *self | ||
20 | } | ||
21 | } | ||
22 | impl<N: AstNode> Copy for AstId<N> {} | ||
23 | |||
24 | impl<N: AstNode> PartialEq for AstId<N> { | ||
25 | fn eq(&self, other: &Self) -> bool { | ||
26 | (self.file_id, self.file_ast_id) == (other.file_id, other.file_ast_id) | ||
27 | } | ||
28 | } | ||
29 | impl<N: AstNode> Eq for AstId<N> {} | ||
30 | impl<N: AstNode> Hash for AstId<N> { | ||
31 | fn hash<H: Hasher>(&self, hasher: &mut H) { | ||
32 | (self.file_id, self.file_ast_id).hash(hasher); | ||
33 | } | ||
34 | } | ||
35 | |||
36 | impl<N: AstNode> AstId<N> { | ||
37 | pub(crate) fn file_id(&self) -> HirFileId { | ||
38 | self.file_id | ||
39 | } | ||
40 | |||
41 | pub(crate) fn to_node(&self, db: &impl DefDatabase) -> TreeArc<N> { | ||
42 | let syntax_node = db.ast_id_to_node(self.file_id, self.file_ast_id.raw); | ||
43 | N::cast(&syntax_node).unwrap().to_owned() | ||
44 | } | ||
45 | } | ||
46 | |||
47 | /// `AstId` points to an AST node in a specific file. | ||
48 | #[derive(Debug)] | ||
49 | pub(crate) struct FileAstId<N: AstNode> { | ||
50 | raw: ErasedFileAstId, | ||
51 | _ty: PhantomData<N>, | ||
52 | } | ||
53 | |||
54 | impl<N: AstNode> Clone for FileAstId<N> { | ||
55 | fn clone(&self) -> FileAstId<N> { | ||
56 | *self | ||
57 | } | ||
58 | } | ||
59 | impl<N: AstNode> Copy for FileAstId<N> {} | ||
13 | 60 | ||
14 | impl SourceFileItemId { | 61 | impl<N: AstNode> PartialEq for FileAstId<N> { |
15 | pub(crate) fn with_file_id(self, file_id: HirFileId) -> SourceItemId { | 62 | fn eq(&self, other: &Self) -> bool { |
16 | SourceItemId { file_id, item_id: self } | 63 | self.raw == other.raw |
64 | } | ||
65 | } | ||
66 | impl<N: AstNode> Eq for FileAstId<N> {} | ||
67 | impl<N: AstNode> Hash for FileAstId<N> { | ||
68 | fn hash<H: Hasher>(&self, hasher: &mut H) { | ||
69 | self.raw.hash(hasher); | ||
17 | } | 70 | } |
18 | } | 71 | } |
19 | 72 | ||
20 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 73 | impl<N: AstNode> FileAstId<N> { |
21 | pub struct SourceItemId { | 74 | pub(crate) fn with_file_id(self, file_id: HirFileId) -> AstId<N> { |
22 | pub(crate) file_id: HirFileId, | 75 | AstId { file_id, file_ast_id: self } |
23 | pub(crate) item_id: SourceFileItemId, | 76 | } |
24 | } | 77 | } |
25 | 78 | ||
26 | /// Maps items' `SyntaxNode`s to `SourceFileItemId`s and back. | 79 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] |
80 | pub struct ErasedFileAstId(RawId); | ||
81 | impl_arena_id!(ErasedFileAstId); | ||
82 | |||
83 | /// Maps items' `SyntaxNode`s to `ErasedFileAstId`s and back. | ||
27 | #[derive(Debug, PartialEq, Eq)] | 84 | #[derive(Debug, PartialEq, Eq)] |
28 | pub struct SourceFileItems { | 85 | pub struct AstIdMap { |
29 | file_id: HirFileId, | 86 | arena: Arena<ErasedFileAstId, SyntaxNodePtr>, |
30 | arena: Arena<SourceFileItemId, SyntaxNodePtr>, | ||
31 | } | 87 | } |
32 | 88 | ||
33 | impl SourceFileItems { | 89 | impl AstIdMap { |
34 | pub(crate) fn file_items_query( | 90 | pub(crate) fn ast_id_map_query(db: &impl DefDatabase, file_id: HirFileId) -> Arc<AstIdMap> { |
35 | db: &impl DefDatabase, | ||
36 | file_id: HirFileId, | ||
37 | ) -> Arc<SourceFileItems> { | ||
38 | let source_file = db.hir_parse(file_id); | 91 | let source_file = db.hir_parse(file_id); |
39 | Arc::new(SourceFileItems::from_source_file(&source_file, file_id)) | 92 | Arc::new(AstIdMap::from_source_file(&source_file)) |
40 | } | 93 | } |
41 | 94 | ||
42 | pub(crate) fn file_item_query( | 95 | pub(crate) fn file_item_query( |
43 | db: &impl DefDatabase, | 96 | db: &impl DefDatabase, |
44 | source_item_id: SourceItemId, | 97 | file_id: HirFileId, |
98 | ast_id: ErasedFileAstId, | ||
45 | ) -> TreeArc<SyntaxNode> { | 99 | ) -> TreeArc<SyntaxNode> { |
46 | let source_file = db.hir_parse(source_item_id.file_id); | 100 | let source_file = db.hir_parse(file_id); |
47 | db.file_items(source_item_id.file_id)[source_item_id.item_id] | 101 | db.ast_id_map(file_id).arena[ast_id].to_node(&source_file).to_owned() |
48 | .to_node(&source_file) | ||
49 | .to_owned() | ||
50 | } | 102 | } |
51 | 103 | ||
52 | pub(crate) fn from_source_file( | 104 | pub(crate) fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> { |
53 | source_file: &SourceFile, | 105 | let ptr = SyntaxNodePtr::new(item.syntax()); |
54 | file_id: HirFileId, | 106 | let raw = match self.arena.iter().find(|(_id, i)| **i == ptr) { |
55 | ) -> SourceFileItems { | 107 | Some((it, _)) => it, |
56 | let mut res = SourceFileItems { file_id, arena: Arena::default() }; | 108 | None => panic!( |
109 | "Can't find {:?} in AstIdMap:\n{:?}", | ||
110 | item.syntax(), | ||
111 | self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), | ||
112 | ), | ||
113 | }; | ||
114 | |||
115 | FileAstId { raw, _ty: PhantomData } | ||
116 | } | ||
117 | |||
118 | fn from_source_file(source_file: &SourceFile) -> AstIdMap { | ||
119 | let mut res = AstIdMap { arena: Arena::default() }; | ||
57 | // By walking the tree in bread-first order we make sure that parents | 120 | // By walking the tree in bread-first order we make sure that parents |
58 | // get lower ids then children. That is, adding a new child does not | 121 | // get lower ids then children. That is, adding a new child does not |
59 | // change parent's id. This means that, say, adding a new function to a | 122 | // change parent's id. This means that, say, adding a new function to a |
@@ -68,35 +131,9 @@ impl SourceFileItems { | |||
68 | res | 131 | res |
69 | } | 132 | } |
70 | 133 | ||
71 | fn alloc(&mut self, item: &SyntaxNode) -> SourceFileItemId { | 134 | fn alloc(&mut self, item: &SyntaxNode) -> ErasedFileAstId { |
72 | self.arena.alloc(SyntaxNodePtr::new(item)) | 135 | self.arena.alloc(SyntaxNodePtr::new(item)) |
73 | } | 136 | } |
74 | pub(crate) fn id_of(&self, file_id: HirFileId, item: &SyntaxNode) -> SourceFileItemId { | ||
75 | assert_eq!( | ||
76 | self.file_id, file_id, | ||
77 | "SourceFileItems: wrong file, expected {:?}, got {:?}", | ||
78 | self.file_id, file_id | ||
79 | ); | ||
80 | self.id_of_unchecked(item) | ||
81 | } | ||
82 | pub(crate) fn id_of_unchecked(&self, item: &SyntaxNode) -> SourceFileItemId { | ||
83 | let ptr = SyntaxNodePtr::new(item); | ||
84 | if let Some((id, _)) = self.arena.iter().find(|(_id, i)| **i == ptr) { | ||
85 | return id; | ||
86 | } | ||
87 | panic!( | ||
88 | "Can't find {:?} in SourceFileItems:\n{:?}", | ||
89 | item, | ||
90 | self.arena.iter().map(|(_id, i)| i).collect::<Vec<_>>(), | ||
91 | ); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | impl std::ops::Index<SourceFileItemId> for SourceFileItems { | ||
96 | type Output = SyntaxNodePtr; | ||
97 | fn index(&self, idx: SourceFileItemId) -> &SyntaxNodePtr { | ||
98 | &self.arena[idx] | ||
99 | } | ||
100 | } | 137 | } |
101 | 138 | ||
102 | /// Walks the subtree in bfs order, calling `f` for each node. | 139 | /// Walks the subtree in bfs order, calling `f` for each node. |