aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_analysis/src/goto_defenition.rs2
-rw-r--r--crates/ra_analysis/src/hover.rs17
-rw-r--r--crates/ra_analysis/src/imp.rs62
-rw-r--r--crates/ra_analysis/src/lib.rs20
4 files changed, 11 insertions, 90 deletions
diff --git a/crates/ra_analysis/src/goto_defenition.rs b/crates/ra_analysis/src/goto_defenition.rs
index 08d1809ee..e37421f8d 100644
--- a/crates/ra_analysis/src/goto_defenition.rs
+++ b/crates/ra_analysis/src/goto_defenition.rs
@@ -20,7 +20,7 @@ pub(crate) fn goto_defenition(
20 Ok(None) 20 Ok(None)
21} 21}
22 22
23fn reference_defenition( 23pub(crate) fn reference_defenition(
24 db: &RootDatabase, 24 db: &RootDatabase,
25 file_id: FileId, 25 file_id: FileId,
26 name_ref: ast::NameRef, 26 name_ref: ast::NameRef,
diff --git a/crates/ra_analysis/src/hover.rs b/crates/ra_analysis/src/hover.rs
index 766fa0547..758de376e 100644
--- a/crates/ra_analysis/src/hover.rs
+++ b/crates/ra_analysis/src/hover.rs
@@ -1,4 +1,5 @@
1use ra_db::{Cancelable, SyntaxDatabase}; 1use ra_db::{Cancelable, SyntaxDatabase};
2use ra_editor::find_node_at_offset;
2use ra_syntax::{ 3use ra_syntax::{
3 AstNode, SyntaxNode, 4 AstNode, SyntaxNode,
4 ast::{self, NameOwner}, 5 ast::{self, NameOwner},
@@ -11,18 +12,18 @@ pub(crate) fn hover(
11 db: &RootDatabase, 12 db: &RootDatabase,
12 position: FilePosition, 13 position: FilePosition,
13) -> Cancelable<Option<RangeInfo<String>>> { 14) -> Cancelable<Option<RangeInfo<String>>> {
15 let file = db.source_file(position.file_id);
14 let mut res = Vec::new(); 16 let mut res = Vec::new();
15 let range = if let Some(rr) = db.approximately_resolve_symbol(position)? { 17 let range = if let Some(name_ref) =
16 for nav in rr.resolves_to { 18 find_node_at_offset::<ast::NameRef>(file.syntax(), position.offset)
19 {
20 let navs = crate::goto_defenition::reference_defenition(db, position.file_id, name_ref)?;
21 for nav in navs {
17 res.extend(doc_text_for(db, nav)?) 22 res.extend(doc_text_for(db, nav)?)
18 } 23 }
19 rr.reference_range 24 name_ref.syntax().range()
20 } else { 25 } else {
21 let file = db.source_file(position.file_id); 26 let expr: ast::Expr = ctry!(find_node_at_offset(file.syntax(), position.offset));
22 let expr: ast::Expr = ctry!(ra_editor::find_node_at_offset(
23 file.syntax(),
24 position.offset
25 ));
26 let frange = FileRange { 27 let frange = FileRange {
27 file_id: position.file_id, 28 file_id: position.file_id,
28 range: expr.syntax().range(), 29 range: expr.syntax().range(),
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs
index 6df118c20..6ab3c5476 100644
--- a/crates/ra_analysis/src/imp.rs
+++ b/crates/ra_analysis/src/imp.rs
@@ -18,7 +18,7 @@ use crate::{
18 AnalysisChange, 18 AnalysisChange,
19 Cancelable, NavigationTarget, 19 Cancelable, NavigationTarget,
20 CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit, 20 CrateId, db, Diagnostic, FileId, FilePosition, FileRange, FileSystemEdit,
21 Query, ReferenceResolution, RootChange, SourceChange, SourceFileEdit, 21 Query, RootChange, SourceChange, SourceFileEdit,
22 symbol_index::{LibrarySymbolsQuery, FileSymbol}, 22 symbol_index::{LibrarySymbolsQuery, FileSymbol},
23}; 23};
24 24
@@ -139,66 +139,6 @@ impl db::RootDatabase {
139 pub(crate) fn crate_root(&self, crate_id: CrateId) -> FileId { 139 pub(crate) fn crate_root(&self, crate_id: CrateId) -> FileId {
140 self.crate_graph().crate_root(crate_id) 140 self.crate_graph().crate_root(crate_id)
141 } 141 }
142 pub(crate) fn approximately_resolve_symbol(
143 &self,
144 position: FilePosition,
145 ) -> Cancelable<Option<ReferenceResolution>> {
146 let file = self.source_file(position.file_id);
147 let syntax = file.syntax();
148 if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) {
149 let mut rr = ReferenceResolution::new(name_ref.syntax().range());
150 if let Some(fn_descr) =
151 source_binder::function_from_child_node(self, position.file_id, name_ref.syntax())?
152 {
153 let scope = fn_descr.scopes(self);
154 // First try to resolve the symbol locally
155 if let Some(entry) = scope.resolve_local_name(name_ref) {
156 rr.resolves_to.push(NavigationTarget {
157 file_id: position.file_id,
158 name: entry.name().to_string().into(),
159 range: entry.ptr().range(),
160 kind: NAME,
161 ptr: None,
162 });
163 return Ok(Some(rr));
164 };
165 }
166 // If that fails try the index based approach.
167 rr.resolves_to.extend(
168 self.index_resolve(name_ref)?
169 .into_iter()
170 .map(NavigationTarget::from_symbol),
171 );
172 return Ok(Some(rr));
173 }
174 if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) {
175 let mut rr = ReferenceResolution::new(name.syntax().range());
176 if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) {
177 if module.has_semi() {
178 if let Some(child_module) =
179 source_binder::module_from_declaration(self, position.file_id, module)?
180 {
181 let file_id = child_module.file_id();
182 let name = match child_module.name() {
183 Some(name) => name.to_string().into(),
184 None => "".into(),
185 };
186 let symbol = NavigationTarget {
187 file_id,
188 name,
189 range: TextRange::offset_len(0.into(), 0.into()),
190 kind: MODULE,
191 ptr: None,
192 };
193 rr.resolves_to.push(symbol);
194 return Ok(Some(rr));
195 }
196 }
197 }
198 }
199 Ok(None)
200 }
201
202 pub(crate) fn find_all_refs( 142 pub(crate) fn find_all_refs(
203 &self, 143 &self,
204 position: FilePosition, 144 position: FilePosition,
diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs
index 13527e628..4d895b004 100644
--- a/crates/ra_analysis/src/lib.rs
+++ b/crates/ra_analysis/src/lib.rs
@@ -274,26 +274,6 @@ impl<T> RangeInfo<T> {
274 } 274 }
275} 275}
276 276
277/// Result of "goto def" query.
278#[derive(Debug)]
279pub struct ReferenceResolution {
280 /// The range of the reference itself. Client does not know what constitutes
281 /// a reference, it handles us only the offset. It's helpful to tell the
282 /// client where the reference was.
283 pub reference_range: TextRange,
284 /// What this reference resolves to.
285 pub resolves_to: Vec<NavigationTarget>,
286}
287
288impl ReferenceResolution {
289 fn new(reference_range: TextRange) -> ReferenceResolution {
290 ReferenceResolution {
291 reference_range,
292 resolves_to: Vec::new(),
293 }
294 }
295}
296
297/// `AnalysisHost` stores the current state of the world. 277/// `AnalysisHost` stores the current state of the world.
298#[derive(Debug, Default)] 278#[derive(Debug, Default)]
299pub struct AnalysisHost { 279pub struct AnalysisHost {