aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src
diff options
context:
space:
mode:
authorEkaterina Babshukova <[email protected]>2019-10-09 22:25:48 +0100
committerEkaterina Babshukova <[email protected]>2019-10-22 21:47:31 +0100
commit01853e8d6c6f4b44801c74f4fcdef735d9e77b48 (patch)
treee26cd5c77688edd40a56dd140483eb56819ca6bf /crates/ra_ide_api/src
parent121aa35f12d282066651d906ea9a8b2da8209605 (diff)
find scope for `Declaration` item
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r--crates/ra_ide_api/src/goto_definition.rs2
-rw-r--r--crates/ra_ide_api/src/lib.rs1
-rw-r--r--crates/ra_ide_api/src/name_kind.rs65
-rw-r--r--crates/ra_ide_api/src/search_scope.rs64
4 files changed, 86 insertions, 46 deletions
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs
index f49764513..fefd59cdd 100644
--- a/crates/ra_ide_api/src/goto_definition.rs
+++ b/crates/ra_ide_api/src/goto_definition.rs
@@ -207,7 +207,7 @@ fn named_target(file_id: FileId, node: &SyntaxNode) -> Option<NavigationTarget>
207 207
208#[cfg(test)] 208#[cfg(test)]
209mod tests { 209mod tests {
210 use test_utils::covers; 210 // use test_utils::covers;
211 211
212 use crate::mock_analysis::analysis_and_position; 212 use crate::mock_analysis::analysis_and_position;
213 213
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs
index cbf79ce03..2dc3f0944 100644
--- a/crates/ra_ide_api/src/lib.rs
+++ b/crates/ra_ide_api/src/lib.rs
@@ -41,6 +41,7 @@ mod matching_brace;
41mod display; 41mod display;
42mod inlay_hints; 42mod inlay_hints;
43mod wasm_shims; 43mod wasm_shims;
44mod search_scope;
44 45
45#[cfg(test)] 46#[cfg(test)]
46mod marks; 47mod marks;
diff --git a/crates/ra_ide_api/src/name_kind.rs b/crates/ra_ide_api/src/name_kind.rs
index 31f6f277d..6d1eb153f 100644
--- a/crates/ra_ide_api/src/name_kind.rs
+++ b/crates/ra_ide_api/src/name_kind.rs
@@ -2,8 +2,8 @@
2 2
3use hir::{ 3use hir::{
4 db::AstDatabase, Adt, AssocItem, DefWithBody, Either, EnumVariant, FromSource, HasSource, 4 db::AstDatabase, Adt, AssocItem, DefWithBody, Either, EnumVariant, FromSource, HasSource,
5 HirFileId, MacroDef, ModuleDef, ModuleSource, Path, PathResolution, SourceAnalyzer, 5 HirFileId, MacroDef, Module, ModuleDef, ModuleSource, Path, PathResolution, Source,
6 StructField, Ty, VariantDef, 6 SourceAnalyzer, StructField, Ty, VariantDef,
7}; 7};
8use ra_db::FileId; 8use ra_db::FileId;
9use ra_syntax::{ast, ast::VisibilityOwner, AstNode, AstPtr}; 9use ra_syntax::{ast, ast::VisibilityOwner, AstNode, AstPtr};
@@ -22,8 +22,8 @@ pub enum NameKind {
22} 22}
23 23
24pub(crate) struct Declaration { 24pub(crate) struct Declaration {
25 visibility: Option<ast::Visibility>, 25 pub visibility: Option<ast::Visibility>,
26 container: ModuleSource, 26 pub container: Module,
27 pub item: NameKind, 27 pub item: NameKind,
28} 28}
29 29
@@ -80,16 +80,9 @@ pub(crate) fn classify_name_ref(
80 } 80 }
81 } 81 }
82 82
83 let ast = ModuleSource::from_child_node(db, file_id, &parent);
83 let file_id = file_id.into(); 84 let file_id = file_id.into();
84 let container = parent.ancestors().find_map(|node| { 85 let container = Module::from_definition(db, Source { file_id, ast })?;
85 if let Some(it) = ast::Module::cast(node.clone()) {
86 Some(ModuleSource::Module(it))
87 } else if let Some(it) = ast::SourceFile::cast(node.clone()) {
88 Some(ModuleSource::SourceFile(it))
89 } else {
90 None
91 }
92 })?;
93 86
94 if let Some(macro_call) = 87 if let Some(macro_call) =
95 parent.parent().and_then(|node| node.parent()).and_then(ast::MacroCall::cast) 88 parent.parent().and_then(|node| node.parent()).and_then(ast::MacroCall::cast)
@@ -117,7 +110,7 @@ pub(crate) fn classify_name_ref(
117 } 110 }
118 PathResolution::SelfType(impl_block) => { 111 PathResolution::SelfType(impl_block) => {
119 let ty = impl_block.target_ty(db); 112 let ty = impl_block.target_ty(db);
120 let container = impl_block.module().definition_source(db).ast; 113 let container = impl_block.module();
121 Some(Declaration { item: NameKind::SelfType(ty), container, visibility: None }) 114 Some(Declaration { item: NameKind::SelfType(ty), container, visibility: None })
122 } 115 }
123 PathResolution::AssocItem(assoc) => Some(assoc.declaration(db)), 116 PathResolution::AssocItem(assoc) => Some(assoc.declaration(db)),
@@ -184,7 +177,7 @@ fn decl_from_pat(
184 } 177 }
185 })?; 178 })?;
186 let item = NameKind::Pat((def, pat)); 179 let item = NameKind::Pat((def, pat));
187 let container = def.module(db).definition_source(db).ast; 180 let container = def.module(db);
188 Some(Declaration { item, container, visibility: None }) 181 Some(Declaration { item, container, visibility: None })
189} 182}
190 183
@@ -195,7 +188,7 @@ impl HasDeclaration for StructField {
195 fn declaration(self, db: &RootDatabase) -> Declaration { 188 fn declaration(self, db: &RootDatabase) -> Declaration {
196 let item = NameKind::FieldAccess(self); 189 let item = NameKind::FieldAccess(self);
197 let parent = self.parent_def(db); 190 let parent = self.parent_def(db);
198 let container = parent.module(db).definition_source(db).ast; 191 let container = parent.module(db);
199 let visibility = match parent { 192 let visibility = match parent {
200 VariantDef::Struct(s) => s.source(db).ast.visibility(), 193 VariantDef::Struct(s) => s.source(db).ast.visibility(),
201 VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(), 194 VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(),
@@ -225,7 +218,7 @@ impl HasDeclaration for AssocItem {
225 218
226 fn declaration(self, db: &RootDatabase) -> Declaration { 219 fn declaration(self, db: &RootDatabase) -> Declaration {
227 let item = NameKind::AssocItem(self); 220 let item = NameKind::AssocItem(self);
228 let container = self.module(db).definition_source(db).ast; 221 let container = self.module(db);
229 let visibility = match self { 222 let visibility = match self {
230 AssocItem::Function(f) => f.source(db).ast.visibility(), 223 AssocItem::Function(f) => f.source(db).ast.visibility(),
231 AssocItem::Const(c) => c.source(db).ast.visibility(), 224 AssocItem::Const(c) => c.source(db).ast.visibility(),
@@ -255,43 +248,25 @@ impl HasDeclaration for ModuleDef {
255 type Ref = ast::Path; 248 type Ref = ast::Path;
256 249
257 fn declaration(self, db: &RootDatabase) -> Declaration { 250 fn declaration(self, db: &RootDatabase) -> Declaration {
258 // FIXME: use macro
259 let (container, visibility) = match self { 251 let (container, visibility) = match self {
260 ModuleDef::Module(it) => { 252 ModuleDef::Module(it) => {
261 let container = 253 let container = it.parent(db).or_else(|| Some(it)).unwrap();
262 it.parent(db).or_else(|| Some(it)).unwrap().definition_source(db).ast;
263 let visibility = it.declaration_source(db).and_then(|s| s.ast.visibility()); 254 let visibility = it.declaration_source(db).and_then(|s| s.ast.visibility());
264 (container, visibility) 255 (container, visibility)
265 } 256 }
266 ModuleDef::EnumVariant(it) => { 257 ModuleDef::EnumVariant(it) => {
267 let container = it.module(db).definition_source(db).ast; 258 let container = it.module(db);
268 let visibility = it.source(db).ast.parent_enum().visibility(); 259 let visibility = it.source(db).ast.parent_enum().visibility();
269 (container, visibility) 260 (container, visibility)
270 } 261 }
271 ModuleDef::Function(it) => { 262 ModuleDef::Function(it) => (it.module(db), it.source(db).ast.visibility()),
272 (it.module(db).definition_source(db).ast, it.source(db).ast.visibility()) 263 ModuleDef::Const(it) => (it.module(db), it.source(db).ast.visibility()),
273 } 264 ModuleDef::Static(it) => (it.module(db), it.source(db).ast.visibility()),
274 ModuleDef::Const(it) => { 265 ModuleDef::Trait(it) => (it.module(db), it.source(db).ast.visibility()),
275 (it.module(db).definition_source(db).ast, it.source(db).ast.visibility()) 266 ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).ast.visibility()),
276 } 267 ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).ast.visibility()),
277 ModuleDef::Static(it) => { 268 ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).ast.visibility()),
278 (it.module(db).definition_source(db).ast, it.source(db).ast.visibility()) 269 ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).ast.visibility()),
279 }
280 ModuleDef::Trait(it) => {
281 (it.module(db).definition_source(db).ast, it.source(db).ast.visibility())
282 }
283 ModuleDef::TypeAlias(it) => {
284 (it.module(db).definition_source(db).ast, it.source(db).ast.visibility())
285 }
286 ModuleDef::Adt(Adt::Struct(it)) => {
287 (it.module(db).definition_source(db).ast, it.source(db).ast.visibility())
288 }
289 ModuleDef::Adt(Adt::Union(it)) => {
290 (it.module(db).definition_source(db).ast, it.source(db).ast.visibility())
291 }
292 ModuleDef::Adt(Adt::Enum(it)) => {
293 (it.module(db).definition_source(db).ast, it.source(db).ast.visibility())
294 }
295 ModuleDef::BuiltinType(..) => unreachable!(), 270 ModuleDef::BuiltinType(..) => unreachable!(),
296 }; 271 };
297 let item = NameKind::Def(self); 272 let item = NameKind::Def(self);
diff --git a/crates/ra_ide_api/src/search_scope.rs b/crates/ra_ide_api/src/search_scope.rs
new file mode 100644
index 000000000..1cf1aed37
--- /dev/null
+++ b/crates/ra_ide_api/src/search_scope.rs
@@ -0,0 +1,64 @@
1use hir::{DefWithBody, HasSource, ModuleSource};
2use ra_db::{FileId, SourceDatabase};
3use ra_syntax::{AstNode, TextRange};
4
5use crate::{
6 db::RootDatabase,
7 name_kind::{Declaration, NameKind},
8};
9
10pub struct SearchScope {
11 pub scope: Vec<(FileId, Option<TextRange>)>,
12}
13
14impl Declaration {
15 pub fn scope(self, db: &RootDatabase) -> Option<SearchScope> {
16 let module_src = self.container.definition_source(db);
17 let file_id = module_src.file_id.original_file(db);
18
19 if let NameKind::Pat((def, _)) = self.item {
20 let range = match def {
21 DefWithBody::Function(f) => f.source(db).ast.syntax().text_range(),
22 DefWithBody::Const(c) => c.source(db).ast.syntax().text_range(),
23 DefWithBody::Static(s) => s.source(db).ast.syntax().text_range(),
24 };
25 return Some(SearchScope { scope: vec![(file_id, Some(range))] });
26 }
27
28 if let Some(vis) = self.visibility {
29 let source_root_id = db.file_source_root(file_id);
30 let source_root = db.source_root(source_root_id);
31 let mut files = source_root.walk().map(|id| (id.into(), None)).collect::<Vec<_>>();
32
33 if vis.syntax().text() == "pub(crate)" {
34 return Some(SearchScope { scope: files });
35 }
36 if vis.syntax().text() == "pub" {
37 let krate = self.container.krate(db).unwrap();
38 let crate_graph = db.crate_graph();
39
40 for crate_id in crate_graph.iter() {
41 let mut crate_deps = crate_graph.dependencies(crate_id);
42
43 if crate_deps.any(|dep| dep.crate_id() == krate.crate_id()) {
44 let root_file = crate_graph.crate_root(crate_id);
45 let source_root_id = db.file_source_root(root_file);
46 let source_root = db.source_root(source_root_id);
47 files.extend(source_root.walk().map(|id| (id.into(), None)));
48 }
49 }
50
51 return Some(SearchScope { scope: files });
52 }
53 // FIXME: extend to "pub(super)" and "pub(in path)" cases,
54 // then remove `Option`
55 return None;
56 }
57
58 let range = match module_src.ast {
59 ModuleSource::Module(m) => Some(m.syntax().text_range()),
60 ModuleSource::SourceFile(_) => None,
61 };
62 Some(SearchScope { scope: vec![(file_id, range)] })
63 }
64}