aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_ide/src/assists.rs4
-rw-r--r--crates/ra_ide/src/lib.rs1
-rw-r--r--crates/ra_ide/src/references.rs5
-rw-r--r--crates/ra_ide/src/references/classify.rs112
-rw-r--r--crates/ra_ide/src/references/name_definition.rs85
-rw-r--r--crates/ra_ide/src/references/search_scope.rs102
-rw-r--r--crates/ra_ide_db/src/defs.rs196
-rw-r--r--crates/ra_ide_db/src/imports_locator.rs (renamed from crates/ra_ide/src/imports_locator.rs)19
-rw-r--r--crates/ra_ide_db/src/lib.rs2
9 files changed, 264 insertions, 262 deletions
diff --git a/crates/ra_ide/src/assists.rs b/crates/ra_ide/src/assists.rs
index f26047570..4a7d8cfa9 100644
--- a/crates/ra_ide/src/assists.rs
+++ b/crates/ra_ide/src/assists.rs
@@ -3,9 +3,9 @@
3use either::Either; 3use either::Either;
4use ra_assists::{AssistAction, AssistLabel}; 4use ra_assists::{AssistAction, AssistLabel};
5use ra_db::{FilePosition, FileRange}; 5use ra_db::{FilePosition, FileRange};
6use ra_ide_db::RootDatabase; 6use ra_ide_db::{imports_locator::ImportsLocatorIde, RootDatabase};
7 7
8use crate::{imports_locator::ImportsLocatorIde, FileId, SourceChange, SourceFileEdit}; 8use crate::{FileId, SourceChange, SourceFileEdit};
9 9
10pub use ra_assists::AssistId; 10pub use ra_assists::AssistId;
11 11
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index 5fb111a90..689921f3f 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -26,7 +26,6 @@ mod syntax_highlighting;
26mod parent_module; 26mod parent_module;
27mod references; 27mod references;
28mod impls; 28mod impls;
29mod imports_locator;
30mod assists; 29mod assists;
31mod diagnostics; 30mod diagnostics;
32mod syntax_tree; 31mod syntax_tree;
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index b47f8bcd9..c215040f4 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -10,7 +10,6 @@
10//! resolved to the search element definition, we get a reference. 10//! resolved to the search element definition, we get a reference.
11 11
12mod classify; 12mod classify;
13mod name_definition;
14mod rename; 13mod rename;
15mod search_scope; 14mod search_scope;
16 15
@@ -29,9 +28,9 @@ use crate::{display::ToNav, FilePosition, FileRange, NavigationTarget, RangeInfo
29 28
30pub(crate) use self::{ 29pub(crate) use self::{
31 classify::{classify_name, classify_name_ref}, 30 classify::{classify_name, classify_name_ref},
32 name_definition::{NameDefinition, NameKind},
33 rename::rename, 31 rename::rename,
34}; 32};
33pub(crate) use ra_ide_db::defs::{NameDefinition, NameKind};
35 34
36pub use self::search_scope::SearchScope; 35pub use self::search_scope::SearchScope;
37 36
@@ -137,7 +136,7 @@ pub(crate) fn find_all_refs(
137 }; 136 };
138 137
139 let search_scope = { 138 let search_scope = {
140 let base = def.search_scope(db); 139 let base = SearchScope::for_def(&def, db);
141 match search_scope { 140 match search_scope {
142 None => base, 141 None => base,
143 Some(scope) => base.intersection(&scope), 142 Some(scope) => base.intersection(&scope),
diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs
index 758ea4e8b..0326fd379 100644
--- a/crates/ra_ide/src/references/classify.rs
+++ b/crates/ra_ide/src/references/classify.rs
@@ -2,119 +2,13 @@
2 2
3use hir::{InFile, PathResolution, SourceBinder}; 3use hir::{InFile, PathResolution, SourceBinder};
4use ra_prof::profile; 4use ra_prof::profile;
5use ra_syntax::{ast, match_ast, AstNode}; 5use ra_syntax::{ast, AstNode};
6use test_utils::tested_by; 6use test_utils::tested_by;
7 7
8use super::{ 8use super::{NameDefinition, NameKind};
9 name_definition::{from_assoc_item, from_module_def, from_struct_field},
10 NameDefinition, NameKind,
11};
12use ra_ide_db::RootDatabase; 9use ra_ide_db::RootDatabase;
13 10
14pub(crate) fn classify_name( 11pub use ra_ide_db::defs::{classify_name, from_assoc_item, from_module_def, from_struct_field};
15 sb: &mut SourceBinder<RootDatabase>,
16 name: InFile<&ast::Name>,
17) -> Option<NameDefinition> {
18 let _p = profile("classify_name");
19 let parent = name.value.syntax().parent()?;
20
21 match_ast! {
22 match parent {
23 ast::BindPat(it) => {
24 let src = name.with_value(it);
25 let local = sb.to_def(src)?;
26 Some(NameDefinition {
27 visibility: None,
28 container: local.module(sb.db),
29 kind: NameKind::Local(local),
30 })
31 },
32 ast::RecordFieldDef(it) => {
33 let src = name.with_value(it);
34 let field: hir::StructField = sb.to_def(src)?;
35 Some(from_struct_field(sb.db, field))
36 },
37 ast::Module(it) => {
38 let def = sb.to_def(name.with_value(it))?;
39 Some(from_module_def(sb.db, def.into(), None))
40 },
41 ast::StructDef(it) => {
42 let src = name.with_value(it);
43 let def: hir::Struct = sb.to_def(src)?;
44 Some(from_module_def(sb.db, def.into(), None))
45 },
46 ast::EnumDef(it) => {
47 let src = name.with_value(it);
48 let def: hir::Enum = sb.to_def(src)?;
49 Some(from_module_def(sb.db, def.into(), None))
50 },
51 ast::TraitDef(it) => {
52 let src = name.with_value(it);
53 let def: hir::Trait = sb.to_def(src)?;
54 Some(from_module_def(sb.db, def.into(), None))
55 },
56 ast::StaticDef(it) => {
57 let src = name.with_value(it);
58 let def: hir::Static = sb.to_def(src)?;
59 Some(from_module_def(sb.db, def.into(), None))
60 },
61 ast::EnumVariant(it) => {
62 let src = name.with_value(it);
63 let def: hir::EnumVariant = sb.to_def(src)?;
64 Some(from_module_def(sb.db, def.into(), None))
65 },
66 ast::FnDef(it) => {
67 let src = name.with_value(it);
68 let def: hir::Function = sb.to_def(src)?;
69 if parent.parent().and_then(ast::ItemList::cast).is_some() {
70 Some(from_assoc_item(sb.db, def.into()))
71 } else {
72 Some(from_module_def(sb.db, def.into(), None))
73 }
74 },
75 ast::ConstDef(it) => {
76 let src = name.with_value(it);
77 let def: hir::Const = sb.to_def(src)?;
78 if parent.parent().and_then(ast::ItemList::cast).is_some() {
79 Some(from_assoc_item(sb.db, def.into()))
80 } else {
81 Some(from_module_def(sb.db, def.into(), None))
82 }
83 },
84 ast::TypeAliasDef(it) => {
85 let src = name.with_value(it);
86 let def: hir::TypeAlias = sb.to_def(src)?;
87 if parent.parent().and_then(ast::ItemList::cast).is_some() {
88 Some(from_assoc_item(sb.db, def.into()))
89 } else {
90 Some(from_module_def(sb.db, def.into(), None))
91 }
92 },
93 ast::MacroCall(it) => {
94 let src = name.with_value(it);
95 let def = sb.to_def(src.clone())?;
96
97 let module = sb.to_module_def(src.file_id.original_file(sb.db))?;
98
99 Some(NameDefinition {
100 visibility: None,
101 container: module,
102 kind: NameKind::Macro(def),
103 })
104 },
105 ast::TypeParam(it) => {
106 let src = name.with_value(it);
107 let def = sb.to_def(src)?;
108 Some(NameDefinition {
109 visibility: None,
110 container: def.module(sb.db),
111 kind: NameKind::TypeParam(def),
112 })
113 },
114 _ => None,
115 }
116 }
117}
118 12
119pub(crate) fn classify_name_ref( 13pub(crate) fn classify_name_ref(
120 sb: &mut SourceBinder<RootDatabase>, 14 sb: &mut SourceBinder<RootDatabase>,
diff --git a/crates/ra_ide/src/references/name_definition.rs b/crates/ra_ide/src/references/name_definition.rs
deleted file mode 100644
index 71565e6d3..000000000
--- a/crates/ra_ide/src/references/name_definition.rs
+++ /dev/null
@@ -1,85 +0,0 @@
1//! `NameDefinition` keeps information about the element we want to search references for.
2//! The element is represented by `NameKind`. It's located inside some `container` and
3//! has a `visibility`, which defines a search scope.
4//! Note that the reference search is possible for not all of the classified items.
5
6use hir::{
7 Adt, AssocItem, HasSource, ImplBlock, Local, MacroDef, Module, ModuleDef, StructField,
8 TypeParam, VariantDef,
9};
10use ra_syntax::{ast, ast::VisibilityOwner};
11
12use ra_ide_db::RootDatabase;
13
14#[derive(Debug, PartialEq, Eq)]
15pub enum NameKind {
16 Macro(MacroDef),
17 Field(StructField),
18 AssocItem(AssocItem),
19 Def(ModuleDef),
20 SelfType(ImplBlock),
21 Local(Local),
22 TypeParam(TypeParam),
23}
24
25#[derive(PartialEq, Eq)]
26pub(crate) struct NameDefinition {
27 pub visibility: Option<ast::Visibility>,
28 /// FIXME: this doesn't really make sense. For example, builtin types don't
29 /// really have a module.
30 pub container: Module,
31 pub kind: NameKind,
32}
33
34pub(super) fn from_assoc_item(db: &RootDatabase, item: AssocItem) -> NameDefinition {
35 let container = item.module(db);
36 let visibility = match item {
37 AssocItem::Function(f) => f.source(db).value.visibility(),
38 AssocItem::Const(c) => c.source(db).value.visibility(),
39 AssocItem::TypeAlias(a) => a.source(db).value.visibility(),
40 };
41 let kind = NameKind::AssocItem(item);
42 NameDefinition { kind, container, visibility }
43}
44
45pub(super) fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDefinition {
46 let kind = NameKind::Field(field);
47 let parent = field.parent_def(db);
48 let container = parent.module(db);
49 let visibility = match parent {
50 VariantDef::Struct(s) => s.source(db).value.visibility(),
51 VariantDef::Union(e) => e.source(db).value.visibility(),
52 VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(),
53 };
54 NameDefinition { kind, container, visibility }
55}
56
57pub(super) fn from_module_def(
58 db: &RootDatabase,
59 def: ModuleDef,
60 module: Option<Module>,
61) -> NameDefinition {
62 let kind = NameKind::Def(def);
63 let (container, visibility) = match def {
64 ModuleDef::Module(it) => {
65 let container = it.parent(db).or_else(|| Some(it)).unwrap();
66 let visibility = it.declaration_source(db).and_then(|s| s.value.visibility());
67 (container, visibility)
68 }
69 ModuleDef::EnumVariant(it) => {
70 let container = it.module(db);
71 let visibility = it.source(db).value.parent_enum().visibility();
72 (container, visibility)
73 }
74 ModuleDef::Function(it) => (it.module(db), it.source(db).value.visibility()),
75 ModuleDef::Const(it) => (it.module(db), it.source(db).value.visibility()),
76 ModuleDef::Static(it) => (it.module(db), it.source(db).value.visibility()),
77 ModuleDef::Trait(it) => (it.module(db), it.source(db).value.visibility()),
78 ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).value.visibility()),
79 ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).value.visibility()),
80 ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).value.visibility()),
81 ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).value.visibility()),
82 ModuleDef::BuiltinType(..) => (module.unwrap(), None),
83 };
84 NameDefinition { kind, container, visibility }
85}
diff --git a/crates/ra_ide/src/references/search_scope.rs b/crates/ra_ide/src/references/search_scope.rs
index 97c65c2cd..279f57be0 100644
--- a/crates/ra_ide/src/references/search_scope.rs
+++ b/crates/ra_ide/src/references/search_scope.rs
@@ -19,59 +19,13 @@ pub struct SearchScope {
19} 19}
20 20
21impl SearchScope { 21impl SearchScope {
22 fn new(entries: FxHashMap<FileId, Option<TextRange>>) -> SearchScope { 22 pub(crate) fn for_def(def: &NameDefinition, db: &RootDatabase) -> SearchScope {
23 SearchScope { entries }
24 }
25 pub fn single_file(file: FileId) -> SearchScope {
26 SearchScope::new(std::iter::once((file, None)).collect())
27 }
28 pub(crate) fn intersection(&self, other: &SearchScope) -> SearchScope {
29 let (mut small, mut large) = (&self.entries, &other.entries);
30 if small.len() > large.len() {
31 mem::swap(&mut small, &mut large)
32 }
33
34 let res = small
35 .iter()
36 .filter_map(|(file_id, r1)| {
37 let r2 = large.get(file_id)?;
38 let r = intersect_ranges(*r1, *r2)?;
39 Some((*file_id, r))
40 })
41 .collect();
42 return SearchScope::new(res);
43
44 fn intersect_ranges(
45 r1: Option<TextRange>,
46 r2: Option<TextRange>,
47 ) -> Option<Option<TextRange>> {
48 match (r1, r2) {
49 (None, r) | (r, None) => Some(r),
50 (Some(r1), Some(r2)) => {
51 let r = r1.intersection(&r2)?;
52 Some(Some(r))
53 }
54 }
55 }
56 }
57}
58
59impl IntoIterator for SearchScope {
60 type Item = (FileId, Option<TextRange>);
61 type IntoIter = std::collections::hash_map::IntoIter<FileId, Option<TextRange>>;
62 fn into_iter(self) -> Self::IntoIter {
63 self.entries.into_iter()
64 }
65}
66
67impl NameDefinition {
68 pub(crate) fn search_scope(&self, db: &RootDatabase) -> SearchScope {
69 let _p = profile("search_scope"); 23 let _p = profile("search_scope");
70 24
71 let module_src = self.container.definition_source(db); 25 let module_src = def.container.definition_source(db);
72 let file_id = module_src.file_id.original_file(db); 26 let file_id = module_src.file_id.original_file(db);
73 27
74 if let NameKind::Local(var) = self.kind { 28 if let NameKind::Local(var) = def.kind {
75 let range = match var.parent(db) { 29 let range = match var.parent(db) {
76 DefWithBody::Function(f) => f.source(db).value.syntax().text_range(), 30 DefWithBody::Function(f) => f.source(db).value.syntax().text_range(),
77 DefWithBody::Const(c) => c.source(db).value.syntax().text_range(), 31 DefWithBody::Const(c) => c.source(db).value.syntax().text_range(),
@@ -82,10 +36,10 @@ impl NameDefinition {
82 return SearchScope::new(res); 36 return SearchScope::new(res);
83 } 37 }
84 38
85 let vis = self.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or_default(); 39 let vis = def.visibility.as_ref().map(|v| v.syntax().to_string()).unwrap_or_default();
86 40
87 if vis.as_str() == "pub(super)" { 41 if vis.as_str() == "pub(super)" {
88 if let Some(parent_module) = self.container.parent(db) { 42 if let Some(parent_module) = def.container.parent(db) {
89 let mut res = FxHashMap::default(); 43 let mut res = FxHashMap::default();
90 let parent_src = parent_module.definition_source(db); 44 let parent_src = parent_module.definition_source(db);
91 let file_id = parent_src.file_id.original_file(db); 45 let file_id = parent_src.file_id.original_file(db);
@@ -118,7 +72,7 @@ impl NameDefinition {
118 return SearchScope::new(res); 72 return SearchScope::new(res);
119 } 73 }
120 if vis.as_str() == "pub" { 74 if vis.as_str() == "pub" {
121 let krate = self.container.krate(); 75 let krate = def.container.krate();
122 for rev_dep in krate.reverse_dependencies(db) { 76 for rev_dep in krate.reverse_dependencies(db) {
123 let root_file = rev_dep.root_file(db); 77 let root_file = rev_dep.root_file(db);
124 let source_root_id = db.file_source_root(root_file); 78 let source_root_id = db.file_source_root(root_file);
@@ -137,4 +91,48 @@ impl NameDefinition {
137 res.insert(file_id, range); 91 res.insert(file_id, range);
138 SearchScope::new(res) 92 SearchScope::new(res)
139 } 93 }
94
95 fn new(entries: FxHashMap<FileId, Option<TextRange>>) -> SearchScope {
96 SearchScope { entries }
97 }
98 pub fn single_file(file: FileId) -> SearchScope {
99 SearchScope::new(std::iter::once((file, None)).collect())
100 }
101 pub(crate) fn intersection(&self, other: &SearchScope) -> SearchScope {
102 let (mut small, mut large) = (&self.entries, &other.entries);
103 if small.len() > large.len() {
104 mem::swap(&mut small, &mut large)
105 }
106
107 let res = small
108 .iter()
109 .filter_map(|(file_id, r1)| {
110 let r2 = large.get(file_id)?;
111 let r = intersect_ranges(*r1, *r2)?;
112 Some((*file_id, r))
113 })
114 .collect();
115 return SearchScope::new(res);
116
117 fn intersect_ranges(
118 r1: Option<TextRange>,
119 r2: Option<TextRange>,
120 ) -> Option<Option<TextRange>> {
121 match (r1, r2) {
122 (None, r) | (r, None) => Some(r),
123 (Some(r1), Some(r2)) => {
124 let r = r1.intersection(&r2)?;
125 Some(Some(r))
126 }
127 }
128 }
129 }
130}
131
132impl IntoIterator for SearchScope {
133 type Item = (FileId, Option<TextRange>);
134 type IntoIter = std::collections::hash_map::IntoIter<FileId, Option<TextRange>>;
135 fn into_iter(self) -> Self::IntoIter {
136 self.entries.into_iter()
137 }
140} 138}
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
new file mode 100644
index 000000000..cee6dde8e
--- /dev/null
+++ b/crates/ra_ide_db/src/defs.rs
@@ -0,0 +1,196 @@
1//! `NameDefinition` keeps information about the element we want to search references for.
2//! The element is represented by `NameKind`. It's located inside some `container` and
3//! has a `visibility`, which defines a search scope.
4//! Note that the reference search is possible for not all of the classified items.
5
6// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).
7
8use hir::{
9 Adt, AssocItem, HasSource, ImplBlock, InFile, Local, MacroDef, Module, ModuleDef, SourceBinder,
10 StructField, TypeParam, VariantDef,
11};
12use ra_prof::profile;
13use ra_syntax::{
14 ast::{self, AstNode, VisibilityOwner},
15 match_ast,
16};
17
18use crate::RootDatabase;
19
20#[derive(Debug, PartialEq, Eq)]
21pub enum NameKind {
22 Macro(MacroDef),
23 Field(StructField),
24 AssocItem(AssocItem),
25 Def(ModuleDef),
26 SelfType(ImplBlock),
27 Local(Local),
28 TypeParam(TypeParam),
29}
30
31#[derive(PartialEq, Eq)]
32pub struct NameDefinition {
33 pub visibility: Option<ast::Visibility>,
34 /// FIXME: this doesn't really make sense. For example, builtin types don't
35 /// really have a module.
36 pub container: Module,
37 pub kind: NameKind,
38}
39
40pub fn classify_name(
41 sb: &mut SourceBinder<RootDatabase>,
42 name: InFile<&ast::Name>,
43) -> Option<NameDefinition> {
44 let _p = profile("classify_name");
45 let parent = name.value.syntax().parent()?;
46
47 match_ast! {
48 match parent {
49 ast::BindPat(it) => {
50 let src = name.with_value(it);
51 let local = sb.to_def(src)?;
52 Some(NameDefinition {
53 visibility: None,
54 container: local.module(sb.db),
55 kind: NameKind::Local(local),
56 })
57 },
58 ast::RecordFieldDef(it) => {
59 let src = name.with_value(it);
60 let field: hir::StructField = sb.to_def(src)?;
61 Some(from_struct_field(sb.db, field))
62 },
63 ast::Module(it) => {
64 let def = sb.to_def(name.with_value(it))?;
65 Some(from_module_def(sb.db, def.into(), None))
66 },
67 ast::StructDef(it) => {
68 let src = name.with_value(it);
69 let def: hir::Struct = sb.to_def(src)?;
70 Some(from_module_def(sb.db, def.into(), None))
71 },
72 ast::EnumDef(it) => {
73 let src = name.with_value(it);
74 let def: hir::Enum = sb.to_def(src)?;
75 Some(from_module_def(sb.db, def.into(), None))
76 },
77 ast::TraitDef(it) => {
78 let src = name.with_value(it);
79 let def: hir::Trait = sb.to_def(src)?;
80 Some(from_module_def(sb.db, def.into(), None))
81 },
82 ast::StaticDef(it) => {
83 let src = name.with_value(it);
84 let def: hir::Static = sb.to_def(src)?;
85 Some(from_module_def(sb.db, def.into(), None))
86 },
87 ast::EnumVariant(it) => {
88 let src = name.with_value(it);
89 let def: hir::EnumVariant = sb.to_def(src)?;
90 Some(from_module_def(sb.db, def.into(), None))
91 },
92 ast::FnDef(it) => {
93 let src = name.with_value(it);
94 let def: hir::Function = sb.to_def(src)?;
95 if parent.parent().and_then(ast::ItemList::cast).is_some() {
96 Some(from_assoc_item(sb.db, def.into()))
97 } else {
98 Some(from_module_def(sb.db, def.into(), None))
99 }
100 },
101 ast::ConstDef(it) => {
102 let src = name.with_value(it);
103 let def: hir::Const = sb.to_def(src)?;
104 if parent.parent().and_then(ast::ItemList::cast).is_some() {
105 Some(from_assoc_item(sb.db, def.into()))
106 } else {
107 Some(from_module_def(sb.db, def.into(), None))
108 }
109 },
110 ast::TypeAliasDef(it) => {
111 let src = name.with_value(it);
112 let def: hir::TypeAlias = sb.to_def(src)?;
113 if parent.parent().and_then(ast::ItemList::cast).is_some() {
114 Some(from_assoc_item(sb.db, def.into()))
115 } else {
116 Some(from_module_def(sb.db, def.into(), None))
117 }
118 },
119 ast::MacroCall(it) => {
120 let src = name.with_value(it);
121 let def = sb.to_def(src.clone())?;
122
123 let module = sb.to_module_def(src.file_id.original_file(sb.db))?;
124
125 Some(NameDefinition {
126 visibility: None,
127 container: module,
128 kind: NameKind::Macro(def),
129 })
130 },
131 ast::TypeParam(it) => {
132 let src = name.with_value(it);
133 let def = sb.to_def(src)?;
134 Some(NameDefinition {
135 visibility: None,
136 container: def.module(sb.db),
137 kind: NameKind::TypeParam(def),
138 })
139 },
140 _ => None,
141 }
142 }
143}
144
145pub fn from_assoc_item(db: &RootDatabase, item: AssocItem) -> NameDefinition {
146 let container = item.module(db);
147 let visibility = match item {
148 AssocItem::Function(f) => f.source(db).value.visibility(),
149 AssocItem::Const(c) => c.source(db).value.visibility(),
150 AssocItem::TypeAlias(a) => a.source(db).value.visibility(),
151 };
152 let kind = NameKind::AssocItem(item);
153 NameDefinition { kind, container, visibility }
154}
155
156pub fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDefinition {
157 let kind = NameKind::Field(field);
158 let parent = field.parent_def(db);
159 let container = parent.module(db);
160 let visibility = match parent {
161 VariantDef::Struct(s) => s.source(db).value.visibility(),
162 VariantDef::Union(e) => e.source(db).value.visibility(),
163 VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(),
164 };
165 NameDefinition { kind, container, visibility }
166}
167
168pub fn from_module_def(
169 db: &RootDatabase,
170 def: ModuleDef,
171 module: Option<Module>,
172) -> NameDefinition {
173 let kind = NameKind::Def(def);
174 let (container, visibility) = match def {
175 ModuleDef::Module(it) => {
176 let container = it.parent(db).or_else(|| Some(it)).unwrap();
177 let visibility = it.declaration_source(db).and_then(|s| s.value.visibility());
178 (container, visibility)
179 }
180 ModuleDef::EnumVariant(it) => {
181 let container = it.module(db);
182 let visibility = it.source(db).value.parent_enum().visibility();
183 (container, visibility)
184 }
185 ModuleDef::Function(it) => (it.module(db), it.source(db).value.visibility()),
186 ModuleDef::Const(it) => (it.module(db), it.source(db).value.visibility()),
187 ModuleDef::Static(it) => (it.module(db), it.source(db).value.visibility()),
188 ModuleDef::Trait(it) => (it.module(db), it.source(db).value.visibility()),
189 ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).value.visibility()),
190 ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).value.visibility()),
191 ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).value.visibility()),
192 ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).value.visibility()),
193 ModuleDef::BuiltinType(..) => (module.unwrap(), None),
194 };
195 NameDefinition { kind, container, visibility }
196}
diff --git a/crates/ra_ide/src/imports_locator.rs b/crates/ra_ide_db/src/imports_locator.rs
index cfd58aafe..21e637608 100644
--- a/crates/ra_ide/src/imports_locator.rs
+++ b/crates/ra_ide_db/src/imports_locator.rs
@@ -3,24 +3,22 @@
3 3
4use hir::{db::HirDatabase, ModuleDef, SourceBinder}; 4use hir::{db::HirDatabase, ModuleDef, SourceBinder};
5use ra_assists::ImportsLocator; 5use ra_assists::ImportsLocator;
6use ra_ide_db::{
7 symbol_index::{self, FileSymbol},
8 RootDatabase,
9};
10use ra_prof::profile; 6use ra_prof::profile;
11use ra_syntax::{ast, AstNode, SyntaxKind::NAME}; 7use ra_syntax::{ast, AstNode, SyntaxKind::NAME};
12 8
13use crate::{ 9use crate::{
14 references::{classify_name, NameDefinition, NameKind}, 10 defs::classify_name,
15 Query, 11 defs::NameKind,
12 symbol_index::{self, FileSymbol, Query},
13 RootDatabase,
16}; 14};
17 15
18pub(crate) struct ImportsLocatorIde<'a> { 16pub struct ImportsLocatorIde<'a> {
19 source_binder: SourceBinder<'a, RootDatabase>, 17 source_binder: SourceBinder<'a, RootDatabase>,
20} 18}
21 19
22impl<'a> ImportsLocatorIde<'a> { 20impl<'a> ImportsLocatorIde<'a> {
23 pub(crate) fn new(db: &'a RootDatabase) -> Self { 21 pub fn new(db: &'a RootDatabase) -> Self {
24 Self { source_binder: SourceBinder::new(db) } 22 Self { source_binder: SourceBinder::new(db) }
25 } 23 }
26 24
@@ -28,7 +26,7 @@ impl<'a> ImportsLocatorIde<'a> {
28 &mut self, 26 &mut self,
29 db: &impl HirDatabase, 27 db: &impl HirDatabase,
30 import_candidate: &FileSymbol, 28 import_candidate: &FileSymbol,
31 ) -> Option<NameDefinition> { 29 ) -> Option<NameKind> {
32 let _p = profile("get_name_definition"); 30 let _p = profile("get_name_definition");
33 let file_id = import_candidate.file_id.into(); 31 let file_id = import_candidate.file_id.into();
34 let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?); 32 let candidate_node = import_candidate.ptr.to_node(&db.parse_or_expand(file_id)?);
@@ -41,6 +39,7 @@ impl<'a> ImportsLocatorIde<'a> {
41 &mut self.source_binder, 39 &mut self.source_binder,
42 hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? }, 40 hir::InFile { file_id, value: &ast::Name::cast(candidate_name_node)? },
43 ) 41 )
42 .map(|it| it.kind)
44 } 43 }
45} 44}
46 45
@@ -67,7 +66,7 @@ impl ImportsLocator for ImportsLocatorIde<'_> {
67 .into_iter() 66 .into_iter()
68 .chain(lib_results.into_iter()) 67 .chain(lib_results.into_iter())
69 .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate)) 68 .filter_map(|import_candidate| self.get_name_definition(db, &import_candidate))
70 .filter_map(|name_definition_to_import| match name_definition_to_import.kind { 69 .filter_map(|name_definition_to_import| match name_definition_to_import {
71 NameKind::Def(module_def) => Some(module_def), 70 NameKind::Def(module_def) => Some(module_def),
72 _ => None, 71 _ => None,
73 }) 72 })
diff --git a/crates/ra_ide_db/src/lib.rs b/crates/ra_ide_db/src/lib.rs
index e922d1e5f..877ac3c38 100644
--- a/crates/ra_ide_db/src/lib.rs
+++ b/crates/ra_ide_db/src/lib.rs
@@ -7,6 +7,8 @@ pub mod line_index_utils;
7pub mod feature_flags; 7pub mod feature_flags;
8pub mod symbol_index; 8pub mod symbol_index;
9pub mod change; 9pub mod change;
10pub mod defs;
11pub mod imports_locator;
10mod wasm_shims; 12mod wasm_shims;
11 13
12use std::sync::Arc; 14use std::sync::Arc;