aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/nameres/raw.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/nameres/raw.rs')
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs68
1 files changed, 52 insertions, 16 deletions
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index b10e458a2..ecb4d7c03 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -7,24 +7,24 @@
7 7
8use std::{ops::Index, sync::Arc}; 8use std::{ops::Index, sync::Arc};
9 9
10use either::Either;
10use hir_expand::{ 11use hir_expand::{
11 ast_id_map::AstIdMap, 12 ast_id_map::AstIdMap,
12 db::AstDatabase, 13 db::AstDatabase,
13 hygiene::Hygiene, 14 hygiene::Hygiene,
14 name::{AsName, Name}, 15 name::{AsName, Name},
15}; 16};
16use ra_arena::{impl_arena_id, Arena, RawId}; 17use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
17use ra_syntax::{ 18use ra_syntax::{
18 ast::{self, AttrsOwner, NameOwner}, 19 ast::{self, AttrsOwner, NameOwner},
19 AstNode, 20 AstNode, AstPtr,
20}; 21};
21use test_utils::tested_by; 22use test_utils::tested_by;
22 23
23use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile}; 24use crate::{
24 25 attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile,
25#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 26 LocalImportId,
26pub(super) struct LocalImportId(RawId); 27};
27impl_arena_id!(LocalImportId);
28 28
29/// `RawItems` is a set of top-level items in a file (except for impls). 29/// `RawItems` is a set of top-level items in a file (except for impls).
30/// 30///
@@ -41,14 +41,35 @@ pub struct RawItems {
41 items: Vec<RawItem>, 41 items: Vec<RawItem>,
42} 42}
43 43
44#[derive(Debug, Default, PartialEq, Eq)]
45pub struct ImportSourceMap {
46 map: ArenaMap<LocalImportId, ImportSourcePtr>,
47}
48
49type ImportSourcePtr = Either<AstPtr<ast::UseTree>, AstPtr<ast::ExternCrateItem>>;
50
51impl ImportSourceMap {
52 pub fn get(&self, import: LocalImportId) -> ImportSourcePtr {
53 self.map[import].clone()
54 }
55}
56
44impl RawItems { 57impl RawItems {
45 pub(crate) fn raw_items_query( 58 pub(crate) fn raw_items_query(
46 db: &(impl DefDatabase + AstDatabase), 59 db: &(impl DefDatabase + AstDatabase),
47 file_id: HirFileId, 60 file_id: HirFileId,
48 ) -> Arc<RawItems> { 61 ) -> Arc<RawItems> {
62 db.raw_items_with_source_map(file_id).0
63 }
64
65 pub(crate) fn raw_items_with_source_map_query(
66 db: &(impl DefDatabase + AstDatabase),
67 file_id: HirFileId,
68 ) -> (Arc<RawItems>, Arc<ImportSourceMap>) {
49 let mut collector = RawItemsCollector { 69 let mut collector = RawItemsCollector {
50 raw_items: RawItems::default(), 70 raw_items: RawItems::default(),
51 source_ast_id_map: db.ast_id_map(file_id), 71 source_ast_id_map: db.ast_id_map(file_id),
72 imports: Trace::new(),
52 file_id, 73 file_id,
53 hygiene: Hygiene::new(db, file_id), 74 hygiene: Hygiene::new(db, file_id),
54 }; 75 };
@@ -59,8 +80,11 @@ impl RawItems {
59 collector.process_module(None, item_list); 80 collector.process_module(None, item_list);
60 } 81 }
61 } 82 }
62 let raw_items = collector.raw_items; 83 let mut raw_items = collector.raw_items;
63 Arc::new(raw_items) 84 let (arena, map) = collector.imports.into_arena_and_map();
85 raw_items.imports = arena;
86 let source_map = ImportSourceMap { map };
87 (Arc::new(raw_items), Arc::new(source_map))
64 } 88 }
65 89
66 pub(super) fn items(&self) -> &[RawItem] { 90 pub(super) fn items(&self) -> &[RawItem] {
@@ -199,6 +223,7 @@ pub(super) struct ImplData {
199 223
200struct RawItemsCollector { 224struct RawItemsCollector {
201 raw_items: RawItems, 225 raw_items: RawItems,
226 imports: Trace<LocalImportId, ImportData, ImportSourcePtr>,
202 source_ast_id_map: Arc<AstIdMap>, 227 source_ast_id_map: Arc<AstIdMap>,
203 file_id: HirFileId, 228 file_id: HirFileId,
204 hygiene: Hygiene, 229 hygiene: Hygiene,
@@ -305,7 +330,7 @@ impl RawItemsCollector {
305 ModPath::expand_use_item( 330 ModPath::expand_use_item(
306 InFile { value: use_item, file_id: self.file_id }, 331 InFile { value: use_item, file_id: self.file_id },
307 &self.hygiene, 332 &self.hygiene,
308 |path, _use_tree, is_glob, alias| { 333 |path, use_tree, is_glob, alias| {
309 let import_data = ImportData { 334 let import_data = ImportData {
310 path, 335 path,
311 alias, 336 alias,
@@ -314,11 +339,11 @@ impl RawItemsCollector {
314 is_extern_crate: false, 339 is_extern_crate: false,
315 is_macro_use: false, 340 is_macro_use: false,
316 }; 341 };
317 buf.push(import_data); 342 buf.push((import_data, Either::Left(AstPtr::new(use_tree))));
318 }, 343 },
319 ); 344 );
320 for import_data in buf { 345 for (import_data, ptr) in buf {
321 self.push_import(current_module, attrs.clone(), import_data); 346 self.push_import(current_module, attrs.clone(), import_data, ptr);
322 } 347 }
323 } 348 }
324 349
@@ -341,7 +366,12 @@ impl RawItemsCollector {
341 is_extern_crate: true, 366 is_extern_crate: true,
342 is_macro_use, 367 is_macro_use,
343 }; 368 };
344 self.push_import(current_module, attrs, import_data); 369 self.push_import(
370 current_module,
371 attrs,
372 import_data,
373 Either::Right(AstPtr::new(&extern_crate)),
374 );
345 } 375 }
346 } 376 }
347 377
@@ -372,8 +402,14 @@ impl RawItemsCollector {
372 self.push_item(current_module, attrs, RawItemKind::Impl(imp)) 402 self.push_item(current_module, attrs, RawItemKind::Impl(imp))
373 } 403 }
374 404
375 fn push_import(&mut self, current_module: Option<Module>, attrs: Attrs, data: ImportData) { 405 fn push_import(
376 let import = self.raw_items.imports.alloc(data); 406 &mut self,
407 current_module: Option<Module>,
408 attrs: Attrs,
409 data: ImportData,
410 source: ImportSourcePtr,
411 ) {
412 let import = self.imports.alloc(|| source, || data);
377 self.push_item(current_module, attrs, RawItemKind::Import(import)) 413 self.push_item(current_module, attrs, RawItemKind::Import(import))
378 } 414 }
379 415