aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_api/src/references
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_api/src/references')
-rw-r--r--crates/ra_ide_api/src/references/classify.rs40
-rw-r--r--crates/ra_ide_api/src/references/name_definition.rs30
-rw-r--r--crates/ra_ide_api/src/references/rename.rs136
-rw-r--r--crates/ra_ide_api/src/references/search_scope.rs10
4 files changed, 42 insertions, 174 deletions
diff --git a/crates/ra_ide_api/src/references/classify.rs b/crates/ra_ide_api/src/references/classify.rs
index ea9d20e71..4a4b030f8 100644
--- a/crates/ra_ide_api/src/references/classify.rs
+++ b/crates/ra_ide_api/src/references/classify.rs
@@ -13,12 +13,12 @@ use crate::db::RootDatabase;
13 13
14pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Option<NameDefinition> { 14pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Option<NameDefinition> {
15 let _p = profile("classify_name"); 15 let _p = profile("classify_name");
16 let parent = name.ast.syntax().parent()?; 16 let parent = name.value.syntax().parent()?;
17 17
18 match_ast! { 18 match_ast! {
19 match parent { 19 match parent {
20 ast::BindPat(it) => { 20 ast::BindPat(it) => {
21 let src = name.with_ast(it); 21 let src = name.with_value(it);
22 let local = hir::Local::from_source(db, src)?; 22 let local = hir::Local::from_source(db, src)?;
23 Some(NameDefinition { 23 Some(NameDefinition {
24 visibility: None, 24 visibility: None,
@@ -28,7 +28,7 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti
28 }, 28 },
29 ast::RecordFieldDef(it) => { 29 ast::RecordFieldDef(it) => {
30 let ast = hir::FieldSource::Named(it); 30 let ast = hir::FieldSource::Named(it);
31 let src = name.with_ast(ast); 31 let src = name.with_value(ast);
32 let field = hir::StructField::from_source(db, src)?; 32 let field = hir::StructField::from_source(db, src)?;
33 Some(from_struct_field(db, field)) 33 Some(from_struct_field(db, field))
34 }, 34 },
@@ -36,42 +36,42 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti
36 let def = { 36 let def = {
37 if !it.has_semi() { 37 if !it.has_semi() {
38 let ast = hir::ModuleSource::Module(it); 38 let ast = hir::ModuleSource::Module(it);
39 let src = name.with_ast(ast); 39 let src = name.with_value(ast);
40 hir::Module::from_definition(db, src) 40 hir::Module::from_definition(db, src)
41 } else { 41 } else {
42 let src = name.with_ast(it); 42 let src = name.with_value(it);
43 hir::Module::from_declaration(db, src) 43 hir::Module::from_declaration(db, src)
44 } 44 }
45 }?; 45 }?;
46 Some(from_module_def(db, def.into(), None)) 46 Some(from_module_def(db, def.into(), None))
47 }, 47 },
48 ast::StructDef(it) => { 48 ast::StructDef(it) => {
49 let src = name.with_ast(it); 49 let src = name.with_value(it);
50 let def = hir::Struct::from_source(db, src)?; 50 let def = hir::Struct::from_source(db, src)?;
51 Some(from_module_def(db, def.into(), None)) 51 Some(from_module_def(db, def.into(), None))
52 }, 52 },
53 ast::EnumDef(it) => { 53 ast::EnumDef(it) => {
54 let src = name.with_ast(it); 54 let src = name.with_value(it);
55 let def = hir::Enum::from_source(db, src)?; 55 let def = hir::Enum::from_source(db, src)?;
56 Some(from_module_def(db, def.into(), None)) 56 Some(from_module_def(db, def.into(), None))
57 }, 57 },
58 ast::TraitDef(it) => { 58 ast::TraitDef(it) => {
59 let src = name.with_ast(it); 59 let src = name.with_value(it);
60 let def = hir::Trait::from_source(db, src)?; 60 let def = hir::Trait::from_source(db, src)?;
61 Some(from_module_def(db, def.into(), None)) 61 Some(from_module_def(db, def.into(), None))
62 }, 62 },
63 ast::StaticDef(it) => { 63 ast::StaticDef(it) => {
64 let src = name.with_ast(it); 64 let src = name.with_value(it);
65 let def = hir::Static::from_source(db, src)?; 65 let def = hir::Static::from_source(db, src)?;
66 Some(from_module_def(db, def.into(), None)) 66 Some(from_module_def(db, def.into(), None))
67 }, 67 },
68 ast::EnumVariant(it) => { 68 ast::EnumVariant(it) => {
69 let src = name.with_ast(it); 69 let src = name.with_value(it);
70 let def = hir::EnumVariant::from_source(db, src)?; 70 let def = hir::EnumVariant::from_source(db, src)?;
71 Some(from_module_def(db, def.into(), None)) 71 Some(from_module_def(db, def.into(), None))
72 }, 72 },
73 ast::FnDef(it) => { 73 ast::FnDef(it) => {
74 let src = name.with_ast(it); 74 let src = name.with_value(it);
75 let def = hir::Function::from_source(db, src)?; 75 let def = hir::Function::from_source(db, src)?;
76 if parent.parent().and_then(ast::ItemList::cast).is_some() { 76 if parent.parent().and_then(ast::ItemList::cast).is_some() {
77 Some(from_assoc_item(db, def.into())) 77 Some(from_assoc_item(db, def.into()))
@@ -80,7 +80,7 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti
80 } 80 }
81 }, 81 },
82 ast::ConstDef(it) => { 82 ast::ConstDef(it) => {
83 let src = name.with_ast(it); 83 let src = name.with_value(it);
84 let def = hir::Const::from_source(db, src)?; 84 let def = hir::Const::from_source(db, src)?;
85 if parent.parent().and_then(ast::ItemList::cast).is_some() { 85 if parent.parent().and_then(ast::ItemList::cast).is_some() {
86 Some(from_assoc_item(db, def.into())) 86 Some(from_assoc_item(db, def.into()))
@@ -89,7 +89,7 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti
89 } 89 }
90 }, 90 },
91 ast::TypeAliasDef(it) => { 91 ast::TypeAliasDef(it) => {
92 let src = name.with_ast(it); 92 let src = name.with_value(it);
93 let def = hir::TypeAlias::from_source(db, src)?; 93 let def = hir::TypeAlias::from_source(db, src)?;
94 if parent.parent().and_then(ast::ItemList::cast).is_some() { 94 if parent.parent().and_then(ast::ItemList::cast).is_some() {
95 Some(from_assoc_item(db, def.into())) 95 Some(from_assoc_item(db, def.into()))
@@ -98,11 +98,11 @@ pub(crate) fn classify_name(db: &RootDatabase, name: Source<&ast::Name>) -> Opti
98 } 98 }
99 }, 99 },
100 ast::MacroCall(it) => { 100 ast::MacroCall(it) => {
101 let src = name.with_ast(it); 101 let src = name.with_value(it);
102 let def = hir::MacroDef::from_source(db, src.clone())?; 102 let def = hir::MacroDef::from_source(db, src.clone())?;
103 103
104 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax())); 104 let module_src = ModuleSource::from_child_node(db, src.as_ref().map(|it| it.syntax()));
105 let module = Module::from_definition(db, src.with_ast(module_src))?; 105 let module = Module::from_definition(db, src.with_value(module_src))?;
106 106
107 Some(NameDefinition { 107 Some(NameDefinition {
108 visibility: None, 108 visibility: None,
@@ -121,7 +121,7 @@ pub(crate) fn classify_name_ref(
121) -> Option<NameDefinition> { 121) -> Option<NameDefinition> {
122 let _p = profile("classify_name_ref"); 122 let _p = profile("classify_name_ref");
123 123
124 let parent = name_ref.ast.syntax().parent()?; 124 let parent = name_ref.value.syntax().parent()?;
125 let analyzer = SourceAnalyzer::new(db, name_ref.map(|it| it.syntax()), None); 125 let analyzer = SourceAnalyzer::new(db, name_ref.map(|it| it.syntax()), None);
126 126
127 if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { 127 if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
@@ -142,16 +142,16 @@ pub(crate) fn classify_name_ref(
142 tested_by!(goto_definition_works_for_record_fields); 142 tested_by!(goto_definition_works_for_record_fields);
143 if let Some(record_lit) = record_field.syntax().ancestors().find_map(ast::RecordLit::cast) { 143 if let Some(record_lit) = record_field.syntax().ancestors().find_map(ast::RecordLit::cast) {
144 let variant_def = analyzer.resolve_record_literal(&record_lit)?; 144 let variant_def = analyzer.resolve_record_literal(&record_lit)?;
145 let hir_path = Path::from_name_ref(name_ref.ast); 145 let hir_path = Path::from_name_ref(name_ref.value);
146 let hir_name = hir_path.as_ident()?; 146 let hir_name = hir_path.as_ident()?;
147 let field = variant_def.field(db, hir_name)?; 147 let field = variant_def.field(db, hir_name)?;
148 return Some(from_struct_field(db, field)); 148 return Some(from_struct_field(db, field));
149 } 149 }
150 } 150 }
151 151
152 let ast = ModuleSource::from_child_node(db, name_ref.with_ast(&parent)); 152 let ast = ModuleSource::from_child_node(db, name_ref.with_value(&parent));
153 // FIXME: find correct container and visibility for each case 153 // FIXME: find correct container and visibility for each case
154 let container = Module::from_definition(db, name_ref.with_ast(ast))?; 154 let container = Module::from_definition(db, name_ref.with_value(ast))?;
155 let visibility = None; 155 let visibility = None;
156 156
157 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { 157 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
@@ -162,7 +162,7 @@ pub(crate) fn classify_name_ref(
162 } 162 }
163 } 163 }
164 164
165 let path = name_ref.ast.syntax().ancestors().find_map(ast::Path::cast)?; 165 let path = name_ref.value.syntax().ancestors().find_map(ast::Path::cast)?;
166 let resolved = analyzer.resolve_path(db, &path)?; 166 let resolved = analyzer.resolve_path(db, &path)?;
167 match resolved { 167 match resolved {
168 PathResolution::Def(def) => Some(from_module_def(db, def, Some(container))), 168 PathResolution::Def(def) => Some(from_module_def(db, def, Some(container))),
diff --git a/crates/ra_ide_api/src/references/name_definition.rs b/crates/ra_ide_api/src/references/name_definition.rs
index ccd75278a..aca23f79e 100644
--- a/crates/ra_ide_api/src/references/name_definition.rs
+++ b/crates/ra_ide_api/src/references/name_definition.rs
@@ -32,9 +32,9 @@ pub(crate) struct NameDefinition {
32pub(super) fn from_assoc_item(db: &RootDatabase, item: AssocItem) -> NameDefinition { 32pub(super) fn from_assoc_item(db: &RootDatabase, item: AssocItem) -> NameDefinition {
33 let container = item.module(db); 33 let container = item.module(db);
34 let visibility = match item { 34 let visibility = match item {
35 AssocItem::Function(f) => f.source(db).ast.visibility(), 35 AssocItem::Function(f) => f.source(db).value.visibility(),
36 AssocItem::Const(c) => c.source(db).ast.visibility(), 36 AssocItem::Const(c) => c.source(db).value.visibility(),
37 AssocItem::TypeAlias(a) => a.source(db).ast.visibility(), 37 AssocItem::TypeAlias(a) => a.source(db).value.visibility(),
38 }; 38 };
39 let kind = NameKind::AssocItem(item); 39 let kind = NameKind::AssocItem(item);
40 NameDefinition { kind, container, visibility } 40 NameDefinition { kind, container, visibility }
@@ -45,8 +45,8 @@ pub(super) fn from_struct_field(db: &RootDatabase, field: StructField) -> NameDe
45 let parent = field.parent_def(db); 45 let parent = field.parent_def(db);
46 let container = parent.module(db); 46 let container = parent.module(db);
47 let visibility = match parent { 47 let visibility = match parent {
48 VariantDef::Struct(s) => s.source(db).ast.visibility(), 48 VariantDef::Struct(s) => s.source(db).value.visibility(),
49 VariantDef::EnumVariant(e) => e.source(db).ast.parent_enum().visibility(), 49 VariantDef::EnumVariant(e) => e.source(db).value.parent_enum().visibility(),
50 }; 50 };
51 NameDefinition { kind, container, visibility } 51 NameDefinition { kind, container, visibility }
52} 52}
@@ -60,22 +60,22 @@ pub(super) fn from_module_def(
60 let (container, visibility) = match def { 60 let (container, visibility) = match def {
61 ModuleDef::Module(it) => { 61 ModuleDef::Module(it) => {
62 let container = it.parent(db).or_else(|| Some(it)).unwrap(); 62 let container = it.parent(db).or_else(|| Some(it)).unwrap();
63 let visibility = it.declaration_source(db).and_then(|s| s.ast.visibility()); 63 let visibility = it.declaration_source(db).and_then(|s| s.value.visibility());
64 (container, visibility) 64 (container, visibility)
65 } 65 }
66 ModuleDef::EnumVariant(it) => { 66 ModuleDef::EnumVariant(it) => {
67 let container = it.module(db); 67 let container = it.module(db);
68 let visibility = it.source(db).ast.parent_enum().visibility(); 68 let visibility = it.source(db).value.parent_enum().visibility();
69 (container, visibility) 69 (container, visibility)
70 } 70 }
71 ModuleDef::Function(it) => (it.module(db), it.source(db).ast.visibility()), 71 ModuleDef::Function(it) => (it.module(db), it.source(db).value.visibility()),
72 ModuleDef::Const(it) => (it.module(db), it.source(db).ast.visibility()), 72 ModuleDef::Const(it) => (it.module(db), it.source(db).value.visibility()),
73 ModuleDef::Static(it) => (it.module(db), it.source(db).ast.visibility()), 73 ModuleDef::Static(it) => (it.module(db), it.source(db).value.visibility()),
74 ModuleDef::Trait(it) => (it.module(db), it.source(db).ast.visibility()), 74 ModuleDef::Trait(it) => (it.module(db), it.source(db).value.visibility()),
75 ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).ast.visibility()), 75 ModuleDef::TypeAlias(it) => (it.module(db), it.source(db).value.visibility()),
76 ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).ast.visibility()), 76 ModuleDef::Adt(Adt::Struct(it)) => (it.module(db), it.source(db).value.visibility()),
77 ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).ast.visibility()), 77 ModuleDef::Adt(Adt::Union(it)) => (it.module(db), it.source(db).value.visibility()),
78 ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).ast.visibility()), 78 ModuleDef::Adt(Adt::Enum(it)) => (it.module(db), it.source(db).value.visibility()),
79 ModuleDef::BuiltinType(..) => (module.unwrap(), None), 79 ModuleDef::BuiltinType(..) => (module.unwrap(), None),
80 }; 80 };
81 NameDefinition { kind, container, visibility } 81 NameDefinition { kind, container, visibility }
diff --git a/crates/ra_ide_api/src/references/rename.rs b/crates/ra_ide_api/src/references/rename.rs
index 11f81cbb3..d58496049 100644
--- a/crates/ra_ide_api/src/references/rename.rs
+++ b/crates/ra_ide_api/src/references/rename.rs
@@ -55,11 +55,11 @@ fn rename_mod(
55) -> Option<SourceChange> { 55) -> Option<SourceChange> {
56 let mut source_file_edits = Vec::new(); 56 let mut source_file_edits = Vec::new();
57 let mut file_system_edits = Vec::new(); 57 let mut file_system_edits = Vec::new();
58 let module_src = hir::Source { file_id: position.file_id.into(), ast: ast_module.clone() }; 58 let module_src = hir::Source { file_id: position.file_id.into(), value: ast_module.clone() };
59 if let Some(module) = hir::Module::from_declaration(db, module_src) { 59 if let Some(module) = hir::Module::from_declaration(db, module_src) {
60 let src = module.definition_source(db); 60 let src = module.definition_source(db);
61 let file_id = src.file_id.original_file(db); 61 let file_id = src.file_id.original_file(db);
62 match src.ast { 62 match src.value {
63 ModuleSource::SourceFile(..) => { 63 ModuleSource::SourceFile(..) => {
64 let mod_path: RelativePathBuf = db.file_relative_path(file_id); 64 let mod_path: RelativePathBuf = db.file_relative_path(file_id);
65 // mod is defined in path/to/dir/mod.rs 65 // mod is defined in path/to/dir/mod.rs
@@ -121,141 +121,9 @@ mod tests {
121 121
122 use crate::{ 122 use crate::{
123 mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId, 123 mock_analysis::analysis_and_position, mock_analysis::single_file_with_position, FileId,
124 ReferenceSearchResult,
125 }; 124 };
126 125
127 #[test] 126 #[test]
128 fn test_find_all_refs_for_local() {
129 let code = r#"
130 fn main() {
131 let mut i = 1;
132 let j = 1;
133 i = i<|> + j;
134
135 {
136 i = 0;
137 }
138
139 i = 5;
140 }"#;
141
142 let refs = get_all_refs(code);
143 assert_eq!(refs.len(), 5);
144 }
145
146 #[test]
147 fn test_find_all_refs_for_param_inside() {
148 let code = r#"
149 fn foo(i : u32) -> u32 {
150 i<|>
151 }"#;
152
153 let refs = get_all_refs(code);
154 assert_eq!(refs.len(), 2);
155 }
156
157 #[test]
158 fn test_find_all_refs_for_fn_param() {
159 let code = r#"
160 fn foo(i<|> : u32) -> u32 {
161 i
162 }"#;
163
164 let refs = get_all_refs(code);
165 assert_eq!(refs.len(), 2);
166 }
167
168 #[test]
169 fn test_find_all_refs_field_name() {
170 let code = r#"
171 //- /lib.rs
172 struct Foo {
173 pub spam<|>: u32,
174 }
175
176 fn main(s: Foo) {
177 let f = s.spam;
178 }
179 "#;
180
181 let refs = get_all_refs(code);
182 assert_eq!(refs.len(), 2);
183 }
184
185 #[test]
186 fn test_find_all_refs_impl_item_name() {
187 let code = r#"
188 //- /lib.rs
189 struct Foo;
190 impl Foo {
191 fn f<|>(&self) { }
192 }
193 "#;
194
195 let refs = get_all_refs(code);
196 assert_eq!(refs.len(), 1);
197 }
198
199 #[test]
200 fn test_find_all_refs_enum_var_name() {
201 let code = r#"
202 //- /lib.rs
203 enum Foo {
204 A,
205 B<|>,
206 C,
207 }
208 "#;
209
210 let refs = get_all_refs(code);
211 assert_eq!(refs.len(), 1);
212 }
213
214 #[test]
215 fn test_find_all_refs_modules() {
216 let code = r#"
217 //- /lib.rs
218 pub mod foo;
219 pub mod bar;
220
221 fn f() {
222 let i = foo::Foo { n: 5 };
223 }
224
225 //- /foo.rs
226 use crate::bar;
227
228 pub struct Foo {
229 pub n: u32,
230 }
231
232 fn f() {
233 let i = bar::Bar { n: 5 };
234 }
235
236 //- /bar.rs
237 use crate::foo;
238
239 pub struct Bar {
240 pub n: u32,
241 }
242
243 fn f() {
244 let i = foo::Foo<|> { n: 5 };
245 }
246 "#;
247
248 let (analysis, pos) = analysis_and_position(code);
249 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
250 assert_eq!(refs.len(), 3);
251 }
252
253 fn get_all_refs(text: &str) -> ReferenceSearchResult {
254 let (analysis, position) = single_file_with_position(text);
255 analysis.find_all_refs(position, None).unwrap().unwrap()
256 }
257
258 #[test]
259 fn test_rename_for_local() { 127 fn test_rename_for_local() {
260 test_rename( 128 test_rename(
261 r#" 129 r#"
diff --git a/crates/ra_ide_api/src/references/search_scope.rs b/crates/ra_ide_api/src/references/search_scope.rs
index 2907787c2..f5c9589f4 100644
--- a/crates/ra_ide_api/src/references/search_scope.rs
+++ b/crates/ra_ide_api/src/references/search_scope.rs
@@ -73,9 +73,9 @@ impl NameDefinition {
73 73
74 if let NameKind::Local(var) = self.kind { 74 if let NameKind::Local(var) = self.kind {
75 let range = match var.parent(db) { 75 let range = match var.parent(db) {
76 DefWithBody::Function(f) => f.source(db).ast.syntax().text_range(), 76 DefWithBody::Function(f) => f.source(db).value.syntax().text_range(),
77 DefWithBody::Const(c) => c.source(db).ast.syntax().text_range(), 77 DefWithBody::Const(c) => c.source(db).value.syntax().text_range(),
78 DefWithBody::Static(s) => s.source(db).ast.syntax().text_range(), 78 DefWithBody::Static(s) => s.source(db).value.syntax().text_range(),
79 }; 79 };
80 let mut res = FxHashMap::default(); 80 let mut res = FxHashMap::default();
81 res.insert(file_id, Some(range)); 81 res.insert(file_id, Some(range));
@@ -91,7 +91,7 @@ impl NameDefinition {
91 let parent_src = parent_module.definition_source(db); 91 let parent_src = parent_module.definition_source(db);
92 let file_id = parent_src.file_id.original_file(db); 92 let file_id = parent_src.file_id.original_file(db);
93 93
94 match parent_src.ast { 94 match parent_src.value {
95 ModuleSource::Module(m) => { 95 ModuleSource::Module(m) => {
96 let range = Some(m.syntax().text_range()); 96 let range = Some(m.syntax().text_range());
97 res.insert(file_id, range); 97 res.insert(file_id, range);
@@ -135,7 +135,7 @@ impl NameDefinition {
135 } 135 }
136 136
137 let mut res = FxHashMap::default(); 137 let mut res = FxHashMap::default();
138 let range = match module_src.ast { 138 let range = match module_src.value {
139 ModuleSource::Module(m) => Some(m.syntax().text_range()), 139 ModuleSource::Module(m) => Some(m.syntax().text_range()),
140 ModuleSource::SourceFile(_) => None, 140 ModuleSource::SourceFile(_) => None,
141 }; 141 };