aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/code_model.rs26
-rw-r--r--crates/ra_hir/src/code_model/src.rs47
-rw-r--r--crates/ra_hir/src/db.rs2
-rw-r--r--crates/ra_hir/src/lib.rs5
-rw-r--r--crates/ra_ide_api/src/completion/complete_path.rs4
5 files changed, 43 insertions, 41 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 4b3ec5457..50c9a79fc 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -9,7 +9,7 @@ use hir_def::{
9 body::scope::ExprScopes, 9 body::scope::ExprScopes,
10 builtin_type::BuiltinType, 10 builtin_type::BuiltinType,
11 docs::Documentation, 11 docs::Documentation,
12 nameres::per_ns::PerNs, 12 nameres::{per_ns::PerNs, raw::ImportId},
13 resolver::{HasResolver, TypeNs}, 13 resolver::{HasResolver, TypeNs},
14 type_ref::TypeRef, 14 type_ref::TypeRef,
15 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, 15 ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup,
@@ -30,7 +30,7 @@ use crate::{
30 TypeAliasId, 30 TypeAliasId,
31 }, 31 },
32 ty::{InferenceResult, Namespace, TraitRef}, 32 ty::{InferenceResult, Namespace, TraitRef},
33 Either, HasSource, ImportId, Name, Source, Ty, 33 Either, HasSource, Name, Source, Ty,
34}; 34};
35 35
36/// hir::Crate describes a single crate. It's the main interface with which 36/// hir::Crate describes a single crate. It's the main interface with which
@@ -129,17 +129,6 @@ impl Module {
129 }) 129 })
130 } 130 }
131 131
132 /// Returns the syntax of the last path segment corresponding to this import
133 pub fn import_source(
134 self,
135 db: &impl HirDatabase,
136 import: ImportId,
137 ) -> Either<ast::UseTree, ast::ExternCrateItem> {
138 let src = self.definition_source(db);
139 let (_, source_map) = db.raw_items_with_source_map(src.file_id);
140 source_map.get(&src.value, import)
141 }
142
143 /// Returns the crate this module is part of. 132 /// Returns the crate this module is part of.
144 pub fn krate(self) -> Crate { 133 pub fn krate(self) -> Crate {
145 Crate { crate_id: self.id.krate } 134 Crate { crate_id: self.id.krate }
@@ -189,11 +178,13 @@ impl Module {
189 } 178 }
190 179
191 /// Returns a `ModuleScope`: a set of items, visible in this module. 180 /// Returns a `ModuleScope`: a set of items, visible in this module.
192 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<ImportId>)> { 181 pub fn scope(self, db: &impl HirDatabase) -> Vec<(Name, ScopeDef, Option<Import>)> {
193 db.crate_def_map(self.id.krate)[self.id.module_id] 182 db.crate_def_map(self.id.krate)[self.id.module_id]
194 .scope 183 .scope
195 .entries() 184 .entries()
196 .map(|(name, res)| (name.clone(), res.def.into(), res.import)) 185 .map(|(name, res)| {
186 (name.clone(), res.def.into(), res.import.map(|id| Import { parent: self, id }))
187 })
197 .collect() 188 .collect()
198 } 189 }
199 190
@@ -236,6 +227,11 @@ impl Module {
236 } 227 }
237} 228}
238 229
230pub struct Import {
231 pub(crate) parent: Module,
232 pub(crate) id: ImportId,
233}
234
239#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 235#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
240pub struct StructField { 236pub struct StructField {
241 pub(crate) parent: VariantDef, 237 pub(crate) parent: VariantDef,
diff --git a/crates/ra_hir/src/code_model/src.rs b/crates/ra_hir/src/code_model/src.rs
index 09bacf579..402f821bf 100644
--- a/crates/ra_hir/src/code_model/src.rs
+++ b/crates/ra_hir/src/code_model/src.rs
@@ -5,24 +5,24 @@ use hir_expand::either::Either;
5use ra_syntax::ast::{self, AstNode}; 5use ra_syntax::ast::{self, AstNode};
6 6
7use crate::{ 7use crate::{
8 db::{AstDatabase, DefDatabase, HirDatabase}, 8 db::{DefDatabase, HirDatabase},
9 ids::AstItemDef, 9 ids::AstItemDef,
10 Const, Enum, EnumVariant, FieldSource, Function, HasBody, MacroDef, Module, ModuleSource, 10 Const, Enum, EnumVariant, FieldSource, Function, HasBody, Import, MacroDef, Module,
11 Static, Struct, StructField, Trait, TypeAlias, Union, 11 ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
12}; 12};
13 13
14pub use hir_expand::Source; 14pub use hir_expand::Source;
15 15
16pub trait HasSource { 16pub trait HasSource {
17 type Ast; 17 type Ast;
18 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<Self::Ast>; 18 fn source(self, db: &impl DefDatabase) -> Source<Self::Ast>;
19} 19}
20 20
21/// NB: Module is !HasSource, because it has two source nodes at the same time: 21/// NB: Module is !HasSource, because it has two source nodes at the same time:
22/// definition and declaration. 22/// definition and declaration.
23impl Module { 23impl Module {
24 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. 24 /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items.
25 pub fn definition_source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ModuleSource> { 25 pub fn definition_source(self, db: &impl DefDatabase) -> Source<ModuleSource> {
26 let def_map = db.crate_def_map(self.id.krate); 26 let def_map = db.crate_def_map(self.id.krate);
27 let src = def_map[self.id.module_id].definition_source(db); 27 let src = def_map[self.id.module_id].definition_source(db);
28 src.map(|it| match it { 28 src.map(|it| match it {
@@ -33,10 +33,7 @@ impl Module {
33 33
34 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. 34 /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`.
35 /// `None` for the crate root. 35 /// `None` for the crate root.
36 pub fn declaration_source( 36 pub fn declaration_source(self, db: &impl DefDatabase) -> Option<Source<ast::Module>> {
37 self,
38 db: &(impl DefDatabase + AstDatabase),
39 ) -> Option<Source<ast::Module>> {
40 let def_map = db.crate_def_map(self.id.krate); 37 let def_map = db.crate_def_map(self.id.krate);
41 def_map[self.id.module_id].declaration_source(db) 38 def_map[self.id.module_id].declaration_source(db)
42 } 39 }
@@ -44,7 +41,7 @@ impl Module {
44 41
45impl HasSource for StructField { 42impl HasSource for StructField {
46 type Ast = FieldSource; 43 type Ast = FieldSource;
47 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<FieldSource> { 44 fn source(self, db: &impl DefDatabase) -> Source<FieldSource> {
48 let var = VariantId::from(self.parent); 45 let var = VariantId::from(self.parent);
49 let src = var.child_source(db); 46 let src = var.child_source(db);
50 src.map(|it| match it[self.id].clone() { 47 src.map(|it| match it[self.id].clone() {
@@ -55,64 +52,74 @@ impl HasSource for StructField {
55} 52}
56impl HasSource for Struct { 53impl HasSource for Struct {
57 type Ast = ast::StructDef; 54 type Ast = ast::StructDef;
58 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StructDef> { 55 fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> {
59 self.id.0.source(db) 56 self.id.0.source(db)
60 } 57 }
61} 58}
62impl HasSource for Union { 59impl HasSource for Union {
63 type Ast = ast::StructDef; 60 type Ast = ast::StructDef;
64 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StructDef> { 61 fn source(self, db: &impl DefDatabase) -> Source<ast::StructDef> {
65 self.id.0.source(db) 62 self.id.0.source(db)
66 } 63 }
67} 64}
68impl HasSource for Enum { 65impl HasSource for Enum {
69 type Ast = ast::EnumDef; 66 type Ast = ast::EnumDef;
70 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumDef> { 67 fn source(self, db: &impl DefDatabase) -> Source<ast::EnumDef> {
71 self.id.source(db) 68 self.id.source(db)
72 } 69 }
73} 70}
74impl HasSource for EnumVariant { 71impl HasSource for EnumVariant {
75 type Ast = ast::EnumVariant; 72 type Ast = ast::EnumVariant;
76 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::EnumVariant> { 73 fn source(self, db: &impl DefDatabase) -> Source<ast::EnumVariant> {
77 self.parent.id.child_source(db).map(|map| map[self.id].clone()) 74 self.parent.id.child_source(db).map(|map| map[self.id].clone())
78 } 75 }
79} 76}
80impl HasSource for Function { 77impl HasSource for Function {
81 type Ast = ast::FnDef; 78 type Ast = ast::FnDef;
82 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::FnDef> { 79 fn source(self, db: &impl DefDatabase) -> Source<ast::FnDef> {
83 self.id.lookup(db).source(db) 80 self.id.lookup(db).source(db)
84 } 81 }
85} 82}
86impl HasSource for Const { 83impl HasSource for Const {
87 type Ast = ast::ConstDef; 84 type Ast = ast::ConstDef;
88 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::ConstDef> { 85 fn source(self, db: &impl DefDatabase) -> Source<ast::ConstDef> {
89 self.id.lookup(db).source(db) 86 self.id.lookup(db).source(db)
90 } 87 }
91} 88}
92impl HasSource for Static { 89impl HasSource for Static {
93 type Ast = ast::StaticDef; 90 type Ast = ast::StaticDef;
94 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::StaticDef> { 91 fn source(self, db: &impl DefDatabase) -> Source<ast::StaticDef> {
95 self.id.source(db) 92 self.id.source(db)
96 } 93 }
97} 94}
98impl HasSource for Trait { 95impl HasSource for Trait {
99 type Ast = ast::TraitDef; 96 type Ast = ast::TraitDef;
100 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TraitDef> { 97 fn source(self, db: &impl DefDatabase) -> Source<ast::TraitDef> {
101 self.id.source(db) 98 self.id.source(db)
102 } 99 }
103} 100}
104impl HasSource for TypeAlias { 101impl HasSource for TypeAlias {
105 type Ast = ast::TypeAliasDef; 102 type Ast = ast::TypeAliasDef;
106 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::TypeAliasDef> { 103 fn source(self, db: &impl DefDatabase) -> Source<ast::TypeAliasDef> {
107 self.id.lookup(db).source(db) 104 self.id.lookup(db).source(db)
108 } 105 }
109} 106}
110impl HasSource for MacroDef { 107impl HasSource for MacroDef {
111 type Ast = ast::MacroCall; 108 type Ast = ast::MacroCall;
112 fn source(self, db: &(impl DefDatabase + AstDatabase)) -> Source<ast::MacroCall> { 109 fn source(self, db: &impl DefDatabase) -> Source<ast::MacroCall> {
113 Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) } 110 Source { file_id: self.id.ast_id.file_id(), value: self.id.ast_id.to_node(db) }
114 } 111 }
115} 112}
113impl HasSource for Import {
114 type Ast = Either<ast::UseTree, ast::ExternCrateItem>;
115
116 /// Returns the syntax of the last path segment corresponding to this import
117 fn source(self, db: &impl DefDatabase) -> Source<Self::Ast> {
118 let src = self.parent.definition_source(db);
119 let (_, source_map) = db.raw_items_with_source_map(src.file_id);
120 src.with_value(source_map.get(&src.value, self.id))
121 }
122}
116 123
117pub trait HasBodySource: HasBody + HasSource 124pub trait HasBodySource: HasBody + HasSource
118where 125where
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index 399101b83..3ae5df8d5 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -29,7 +29,7 @@ pub use hir_expand::db::{
29 29
30#[salsa::query_group(HirDatabaseStorage)] 30#[salsa::query_group(HirDatabaseStorage)]
31#[salsa::requires(salsa::Database)] 31#[salsa::requires(salsa::Database)]
32pub trait HirDatabase: DefDatabase + AstDatabase { 32pub trait HirDatabase: DefDatabase {
33 #[salsa::invoke(crate::ty::infer_query)] 33 #[salsa::invoke(crate::ty::infer_query)]
34 fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>; 34 fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>;
35 35
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs
index d42161612..e51d4d063 100644
--- a/crates/ra_hir/src/lib.rs
+++ b/crates/ra_hir/src/lib.rs
@@ -53,8 +53,8 @@ pub use crate::{
53 src::{HasBodySource, HasSource}, 53 src::{HasBodySource, HasSource},
54 Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, DefWithBody, Docs, Enum, 54 Adt, AssocItem, AttrDef, Const, Container, Crate, CrateDependency, DefWithBody, Docs, Enum,
55 EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasAttrs, HasBody, ImplBlock, 55 EnumVariant, FieldSource, Function, GenericDef, GenericParam, HasAttrs, HasBody, ImplBlock,
56 Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, 56 Import, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct,
57 Trait, TypeAlias, Union, VariantDef, 57 StructField, Trait, TypeAlias, Union, VariantDef,
58 }, 58 },
59 expr::ExprScopes, 59 expr::ExprScopes,
60 from_source::FromSource, 60 from_source::FromSource,
@@ -70,7 +70,6 @@ pub use crate::{
70pub use hir_def::{ 70pub use hir_def::{
71 builtin_type::BuiltinType, 71 builtin_type::BuiltinType,
72 docs::Documentation, 72 docs::Documentation,
73 nameres::raw::ImportId,
74 path::{Path, PathKind}, 73 path::{Path, PathKind},
75 type_ref::Mutability, 74 type_ref::Mutability,
76}; 75};
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs
index 802c7701a..63e25e0bf 100644
--- a/crates/ra_ide_api/src/completion/complete_path.rs
+++ b/crates/ra_ide_api/src/completion/complete_path.rs
@@ -1,6 +1,6 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use hir::{Adt, Either, PathResolution}; 3use hir::{Adt, Either, HasSource, PathResolution};
4use ra_syntax::AstNode; 4use ra_syntax::AstNode;
5use test_utils::tested_by; 5use test_utils::tested_by;
6 6
@@ -27,7 +27,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) {
27 } 27 }
28 if Some(module) == ctx.module { 28 if Some(module) == ctx.module {
29 if let Some(import) = import { 29 if let Some(import) = import {
30 if let Either::A(use_tree) = module.import_source(ctx.db, import) { 30 if let Either::A(use_tree) = import.source(ctx.db).value {
31 if use_tree.syntax().text_range().contains_inclusive(ctx.offset) { 31 if use_tree.syntax().text_range().contains_inclusive(ctx.offset) {
32 // for `use self::foo<|>`, don't suggest `foo` as a completion 32 // for `use self::foo<|>`, don't suggest `foo` as a completion
33 tested_by!(dont_complete_current_use); 33 tested_by!(dont_complete_current_use);