diff options
Diffstat (limited to 'crates/ra_analysis/src/imp.rs')
-rw-r--r-- | crates/ra_analysis/src/imp.rs | 238 |
1 files changed, 84 insertions, 154 deletions
diff --git a/crates/ra_analysis/src/imp.rs b/crates/ra_analysis/src/imp.rs index 8a41b3152..f5cb3550e 100644 --- a/crates/ra_analysis/src/imp.rs +++ b/crates/ra_analysis/src/imp.rs | |||
@@ -1,94 +1,33 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | fmt, | 2 | fmt, |
3 | hash::{Hash, Hasher}, | ||
4 | sync::Arc, | 3 | sync::Arc, |
5 | }; | 4 | }; |
6 | 5 | ||
7 | use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit}; | 6 | use ra_editor::{self, find_node_at_offset, FileSymbol, LineIndex, LocalEdit}; |
8 | use ra_syntax::{ | 7 | use ra_syntax::{ |
9 | ast::{self, ArgListOwner, Expr, NameOwner}, | 8 | ast::{self, ArgListOwner, Expr, NameOwner}, |
10 | AstNode, SourceFileNode, SmolStr, | 9 | AstNode, SourceFileNode, |
11 | SyntaxKind::*, | 10 | SyntaxKind::*, |
12 | SyntaxNodeRef, TextRange, TextUnit, | 11 | SyntaxNodeRef, TextRange, TextUnit, |
13 | }; | 12 | }; |
13 | use ra_db::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE, SyntaxDatabase, SourceFileQuery}; | ||
14 | use rayon::prelude::*; | 14 | use rayon::prelude::*; |
15 | use relative_path::RelativePath; | ||
16 | use rustc_hash::FxHashSet; | 15 | use rustc_hash::FxHashSet; |
17 | use salsa::{Database, ParallelDatabase}; | 16 | use salsa::{Database, ParallelDatabase}; |
17 | use hir::{ | ||
18 | self, | ||
19 | FnSignatureInfo, | ||
20 | Problem, | ||
21 | }; | ||
18 | 22 | ||
19 | use crate::{ | 23 | use crate::{ |
20 | completion::{completions, CompletionItem}, | 24 | completion::{completions, CompletionItem}, |
21 | db::{self, FileSyntaxQuery, SyntaxDatabase}, | 25 | db, |
22 | descriptors::{ | 26 | symbol_index::{SymbolIndex, SymbolsDatabase}, |
23 | function::{FnDescriptor, FnId}, | 27 | AnalysisChange, Cancelable, CrateId, Diagnostic, FileId, |
24 | module::{ModuleDescriptor, Problem}, | ||
25 | DeclarationDescriptor, DescriptorDatabase, | ||
26 | }, | ||
27 | input::{FilesDatabase, SourceRoot, SourceRootId, WORKSPACE}, | ||
28 | symbol_index::SymbolIndex, | ||
29 | AnalysisChange, Cancelable, CrateGraph, CrateId, Diagnostic, FileId, FileResolver, | ||
30 | FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit, | 28 | FileSystemEdit, FilePosition, Query, SourceChange, SourceFileNodeEdit, |
31 | }; | 29 | }; |
32 | 30 | ||
33 | #[derive(Clone, Debug)] | ||
34 | pub(crate) struct FileResolverImp { | ||
35 | inner: Arc<FileResolver>, | ||
36 | } | ||
37 | |||
38 | impl PartialEq for FileResolverImp { | ||
39 | fn eq(&self, other: &FileResolverImp) -> bool { | ||
40 | self.inner() == other.inner() | ||
41 | } | ||
42 | } | ||
43 | |||
44 | impl Eq for FileResolverImp {} | ||
45 | |||
46 | impl Hash for FileResolverImp { | ||
47 | fn hash<H: Hasher>(&self, hasher: &mut H) { | ||
48 | self.inner().hash(hasher); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | impl FileResolverImp { | ||
53 | pub(crate) fn new(inner: Arc<FileResolver>) -> FileResolverImp { | ||
54 | FileResolverImp { inner } | ||
55 | } | ||
56 | pub(crate) fn file_stem(&self, file_id: FileId) -> String { | ||
57 | self.inner.file_stem(file_id) | ||
58 | } | ||
59 | pub(crate) fn resolve(&self, file_id: FileId, path: &RelativePath) -> Option<FileId> { | ||
60 | self.inner.resolve(file_id, path) | ||
61 | } | ||
62 | pub(crate) fn debug_path(&self, file_id: FileId) -> Option<std::path::PathBuf> { | ||
63 | self.inner.debug_path(file_id) | ||
64 | } | ||
65 | fn inner(&self) -> *const FileResolver { | ||
66 | &*self.inner | ||
67 | } | ||
68 | } | ||
69 | |||
70 | impl Default for FileResolverImp { | ||
71 | fn default() -> FileResolverImp { | ||
72 | #[derive(Debug)] | ||
73 | struct DummyResolver; | ||
74 | impl FileResolver for DummyResolver { | ||
75 | fn file_stem(&self, _file_: FileId) -> String { | ||
76 | panic!("file resolver not set") | ||
77 | } | ||
78 | fn resolve( | ||
79 | &self, | ||
80 | _file_id: FileId, | ||
81 | _path: &::relative_path::RelativePath, | ||
82 | ) -> Option<FileId> { | ||
83 | panic!("file resolver not set") | ||
84 | } | ||
85 | } | ||
86 | FileResolverImp { | ||
87 | inner: Arc::new(DummyResolver), | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | #[derive(Debug, Default)] | 31 | #[derive(Debug, Default)] |
93 | pub(crate) struct AnalysisHostImpl { | 32 | pub(crate) struct AnalysisHostImpl { |
94 | db: db::RootDatabase, | 33 | db: db::RootDatabase, |
@@ -105,7 +44,7 @@ impl AnalysisHostImpl { | |||
105 | 44 | ||
106 | for (file_id, text) in change.files_changed { | 45 | for (file_id, text) in change.files_changed { |
107 | self.db | 46 | self.db |
108 | .query_mut(crate::input::FileTextQuery) | 47 | .query_mut(ra_db::FileTextQuery) |
109 | .set(file_id, Arc::new(text)) | 48 | .set(file_id, Arc::new(text)) |
110 | } | 49 | } |
111 | if !(change.files_added.is_empty() && change.files_removed.is_empty()) { | 50 | if !(change.files_added.is_empty() && change.files_removed.is_empty()) { |
@@ -115,22 +54,22 @@ impl AnalysisHostImpl { | |||
115 | let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); | 54 | let mut source_root = SourceRoot::clone(&self.db.source_root(WORKSPACE)); |
116 | for (file_id, text) in change.files_added { | 55 | for (file_id, text) in change.files_added { |
117 | self.db | 56 | self.db |
118 | .query_mut(crate::input::FileTextQuery) | 57 | .query_mut(ra_db::FileTextQuery) |
119 | .set(file_id, Arc::new(text)); | 58 | .set(file_id, Arc::new(text)); |
120 | self.db | 59 | self.db |
121 | .query_mut(crate::input::FileSourceRootQuery) | 60 | .query_mut(ra_db::FileSourceRootQuery) |
122 | .set(file_id, crate::input::WORKSPACE); | 61 | .set(file_id, ra_db::WORKSPACE); |
123 | source_root.files.insert(file_id); | 62 | source_root.files.insert(file_id); |
124 | } | 63 | } |
125 | for file_id in change.files_removed { | 64 | for file_id in change.files_removed { |
126 | self.db | 65 | self.db |
127 | .query_mut(crate::input::FileTextQuery) | 66 | .query_mut(ra_db::FileTextQuery) |
128 | .set(file_id, Arc::new(String::new())); | 67 | .set(file_id, Arc::new(String::new())); |
129 | source_root.files.remove(&file_id); | 68 | source_root.files.remove(&file_id); |
130 | } | 69 | } |
131 | source_root.file_resolver = file_resolver; | 70 | source_root.file_resolver = file_resolver; |
132 | self.db | 71 | self.db |
133 | .query_mut(crate::input::SourceRootQuery) | 72 | .query_mut(ra_db::SourceRootQuery) |
134 | .set(WORKSPACE, Arc::new(source_root)) | 73 | .set(WORKSPACE, Arc::new(source_root)) |
135 | } | 74 | } |
136 | if !change.libraries_added.is_empty() { | 75 | if !change.libraries_added.is_empty() { |
@@ -147,10 +86,10 @@ impl AnalysisHostImpl { | |||
147 | library.file_resolver.debug_path(file_id) | 86 | library.file_resolver.debug_path(file_id) |
148 | ); | 87 | ); |
149 | self.db | 88 | self.db |
150 | .query_mut(crate::input::FileSourceRootQuery) | 89 | .query_mut(ra_db::FileSourceRootQuery) |
151 | .set_constant(file_id, source_root_id); | 90 | .set_constant(file_id, source_root_id); |
152 | self.db | 91 | self.db |
153 | .query_mut(crate::input::FileTextQuery) | 92 | .query_mut(ra_db::FileTextQuery) |
154 | .set_constant(file_id, Arc::new(text)); | 93 | .set_constant(file_id, Arc::new(text)); |
155 | } | 94 | } |
156 | let source_root = SourceRoot { | 95 | let source_root = SourceRoot { |
@@ -158,19 +97,19 @@ impl AnalysisHostImpl { | |||
158 | file_resolver: library.file_resolver, | 97 | file_resolver: library.file_resolver, |
159 | }; | 98 | }; |
160 | self.db | 99 | self.db |
161 | .query_mut(crate::input::SourceRootQuery) | 100 | .query_mut(ra_db::SourceRootQuery) |
162 | .set(source_root_id, Arc::new(source_root)); | 101 | .set(source_root_id, Arc::new(source_root)); |
163 | self.db | 102 | self.db |
164 | .query_mut(crate::input::LibrarySymbolsQuery) | 103 | .query_mut(crate::symbol_index::LibrarySymbolsQuery) |
165 | .set(source_root_id, Arc::new(library.symbol_index)); | 104 | .set(source_root_id, Arc::new(library.symbol_index)); |
166 | } | 105 | } |
167 | self.db | 106 | self.db |
168 | .query_mut(crate::input::LibrariesQuery) | 107 | .query_mut(ra_db::LibrariesQuery) |
169 | .set((), Arc::new(libraries)); | 108 | .set((), Arc::new(libraries)); |
170 | } | 109 | } |
171 | if let Some(crate_graph) = change.crate_graph { | 110 | if let Some(crate_graph) = change.crate_graph { |
172 | self.db | 111 | self.db |
173 | .query_mut(crate::input::CrateGraphQuery) | 112 | .query_mut(ra_db::CrateGraphQuery) |
174 | .set((), Arc::new(crate_graph)) | 113 | .set((), Arc::new(crate_graph)) |
175 | } | 114 | } |
176 | } | 115 | } |
@@ -189,7 +128,7 @@ impl fmt::Debug for AnalysisImpl { | |||
189 | 128 | ||
190 | impl AnalysisImpl { | 129 | impl AnalysisImpl { |
191 | pub fn file_syntax(&self, file_id: FileId) -> SourceFileNode { | 130 | pub fn file_syntax(&self, file_id: FileId) -> SourceFileNode { |
192 | self.db.file_syntax(file_id) | 131 | self.db.source_file(file_id) |
193 | } | 132 | } |
194 | pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> { | 133 | pub fn file_line_index(&self, file_id: FileId) -> Arc<LineIndex> { |
195 | self.db.file_lines(file_id) | 134 | self.db.file_lines(file_id) |
@@ -220,14 +159,14 @@ impl AnalysisImpl { | |||
220 | .collect() | 159 | .collect() |
221 | }; | 160 | }; |
222 | self.db | 161 | self.db |
223 | .query(FileSyntaxQuery) | 162 | .query(SourceFileQuery) |
224 | .sweep(salsa::SweepStrategy::default().discard_values()); | 163 | .sweep(salsa::SweepStrategy::default().discard_values()); |
225 | Ok(query.search(&buf)) | 164 | Ok(query.search(&buf)) |
226 | } | 165 | } |
227 | /// This return `Vec`: a module may be included from several places. We | 166 | /// This return `Vec`: a module may be included from several places. We |
228 | /// don't handle this case yet though, so the Vec has length at most one. | 167 | /// don't handle this case yet though, so the Vec has length at most one. |
229 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 168 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
230 | let descr = match ModuleDescriptor::guess_from_position(&*self.db, position)? { | 169 | let descr = match hir::Module::guess_from_position(&*self.db, position)? { |
231 | None => return Ok(Vec::new()), | 170 | None => return Ok(Vec::new()), |
232 | Some(it) => it, | 171 | Some(it) => it, |
233 | }; | 172 | }; |
@@ -246,7 +185,7 @@ impl AnalysisImpl { | |||
246 | } | 185 | } |
247 | /// Returns `Vec` for the same reason as `parent_module` | 186 | /// Returns `Vec` for the same reason as `parent_module` |
248 | pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { | 187 | pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { |
249 | let descr = match ModuleDescriptor::guess_from_file_id(&*self.db, file_id)? { | 188 | let descr = match hir::Module::guess_from_file_id(&*self.db, file_id)? { |
250 | None => return Ok(Vec::new()), | 189 | None => return Ok(Vec::new()), |
251 | Some(it) => it, | 190 | Some(it) => it, |
252 | }; | 191 | }; |
@@ -261,7 +200,7 @@ impl AnalysisImpl { | |||
261 | Ok(crate_id.into_iter().collect()) | 200 | Ok(crate_id.into_iter().collect()) |
262 | } | 201 | } |
263 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { | 202 | pub fn crate_root(&self, crate_id: CrateId) -> FileId { |
264 | self.db.crate_graph().crate_roots[&crate_id] | 203 | self.db.crate_graph().crate_root(crate_id) |
265 | } | 204 | } |
266 | pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> { | 205 | pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> { |
267 | completions(&self.db, position) | 206 | completions(&self.db, position) |
@@ -270,33 +209,36 @@ impl AnalysisImpl { | |||
270 | &self, | 209 | &self, |
271 | position: FilePosition, | 210 | position: FilePosition, |
272 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { | 211 | ) -> Cancelable<Vec<(FileId, FileSymbol)>> { |
273 | let file = self.db.file_syntax(position.file_id); | 212 | let file = self.db.source_file(position.file_id); |
274 | let syntax = file.syntax(); | 213 | let syntax = file.syntax(); |
275 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { | 214 | if let Some(name_ref) = find_node_at_offset::<ast::NameRef>(syntax, position.offset) { |
276 | // First try to resolve the symbol locally | 215 | if let Some(fn_descr) = |
277 | return if let Some((name, range)) = | 216 | hir::Function::guess_for_name_ref(&*self.db, position.file_id, name_ref) |
278 | resolve_local_name(&self.db, position.file_id, name_ref) | ||
279 | { | 217 | { |
280 | let mut vec = vec![]; | 218 | let scope = fn_descr.scope(&*self.db); |
281 | vec.push(( | 219 | // First try to resolve the symbol locally |
282 | position.file_id, | 220 | return if let Some(entry) = scope.resolve_local_name(name_ref) { |
283 | FileSymbol { | 221 | let mut vec = vec![]; |
284 | name, | 222 | vec.push(( |
285 | node_range: range, | 223 | position.file_id, |
286 | kind: NAME, | 224 | FileSymbol { |
287 | }, | 225 | name: entry.name().clone(), |
288 | )); | 226 | node_range: entry.ptr().range(), |
289 | Ok(vec) | 227 | kind: NAME, |
290 | } else { | 228 | }, |
291 | // If that fails try the index based approach. | 229 | )); |
292 | self.index_resolve(name_ref) | 230 | Ok(vec) |
293 | }; | 231 | } else { |
232 | // If that fails try the index based approach. | ||
233 | self.index_resolve(name_ref) | ||
234 | }; | ||
235 | } | ||
294 | } | 236 | } |
295 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { | 237 | if let Some(name) = find_node_at_offset::<ast::Name>(syntax, position.offset) { |
296 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { | 238 | if let Some(module) = name.syntax().parent().and_then(ast::Module::cast) { |
297 | if module.has_semi() { | 239 | if module.has_semi() { |
298 | let parent_module = | 240 | let parent_module = |
299 | ModuleDescriptor::guess_from_file_id(&*self.db, position.file_id)?; | 241 | hir::Module::guess_from_file_id(&*self.db, position.file_id)?; |
300 | let child_name = module.name(); | 242 | let child_name = module.name(); |
301 | match (parent_module, child_name) { | 243 | match (parent_module, child_name) { |
302 | (Some(parent_module), Some(child_name)) => { | 244 | (Some(parent_module), Some(child_name)) => { |
@@ -319,32 +261,42 @@ impl AnalysisImpl { | |||
319 | } | 261 | } |
320 | 262 | ||
321 | pub fn find_all_refs(&self, position: FilePosition) -> Vec<(FileId, TextRange)> { | 263 | pub fn find_all_refs(&self, position: FilePosition) -> Vec<(FileId, TextRange)> { |
322 | let file = self.db.file_syntax(position.file_id); | 264 | let file = self.db.source_file(position.file_id); |
323 | let syntax = file.syntax(); | ||
324 | |||
325 | // Find the binding associated with the offset | 265 | // Find the binding associated with the offset |
326 | let maybe_binding = | 266 | let (binding, descr) = match find_binding(&self.db, &file, position) { |
327 | find_node_at_offset::<ast::BindPat>(syntax, position.offset).or_else(|| { | ||
328 | let name_ref = find_node_at_offset::<ast::NameRef>(syntax, position.offset)?; | ||
329 | let resolved = resolve_local_name(&self.db, position.file_id, name_ref)?; | ||
330 | find_node_at_offset::<ast::BindPat>(syntax, resolved.1.end()) | ||
331 | }); | ||
332 | |||
333 | let binding = match maybe_binding { | ||
334 | None => return Vec::new(), | 267 | None => return Vec::new(), |
335 | Some(it) => it, | 268 | Some(it) => it, |
336 | }; | 269 | }; |
337 | 270 | ||
338 | let decl = DeclarationDescriptor::new(binding); | 271 | let mut ret = vec![(position.file_id, binding.syntax().range())]; |
339 | |||
340 | let mut ret = vec![(position.file_id, decl.range)]; | ||
341 | ret.extend( | 272 | ret.extend( |
342 | decl.find_all_refs() | 273 | descr |
274 | .scope(&*self.db) | ||
275 | .find_all_refs(binding) | ||
343 | .into_iter() | 276 | .into_iter() |
344 | .map(|ref_desc| (position.file_id, ref_desc.range)), | 277 | .map(|ref_desc| (position.file_id, ref_desc.range)), |
345 | ); | 278 | ); |
346 | 279 | ||
347 | ret | 280 | return ret; |
281 | |||
282 | fn find_binding<'a>( | ||
283 | db: &db::RootDatabase, | ||
284 | source_file: &'a SourceFileNode, | ||
285 | position: FilePosition, | ||
286 | ) -> Option<(ast::BindPat<'a>, hir::Function)> { | ||
287 | let syntax = source_file.syntax(); | ||
288 | if let Some(binding) = find_node_at_offset::<ast::BindPat>(syntax, position.offset) { | ||
289 | let descr = hir::Function::guess_for_bind_pat(db, position.file_id, binding)?; | ||
290 | return Some((binding, descr)); | ||
291 | }; | ||
292 | let name_ref = find_node_at_offset::<ast::NameRef>(syntax, position.offset)?; | ||
293 | let descr = hir::Function::guess_for_name_ref(db, position.file_id, name_ref)?; | ||
294 | let scope = descr.scope(db); | ||
295 | let resolved = scope.resolve_local_name(name_ref)?; | ||
296 | let resolved = resolved.ptr().resolve(source_file); | ||
297 | let binding = find_node_at_offset::<ast::BindPat>(syntax, resolved.range().end())?; | ||
298 | Some((binding, descr)) | ||
299 | } | ||
348 | } | 300 | } |
349 | 301 | ||
350 | pub fn doc_comment_for( | 302 | pub fn doc_comment_for( |
@@ -352,13 +304,13 @@ impl AnalysisImpl { | |||
352 | file_id: FileId, | 304 | file_id: FileId, |
353 | symbol: FileSymbol, | 305 | symbol: FileSymbol, |
354 | ) -> Cancelable<Option<String>> { | 306 | ) -> Cancelable<Option<String>> { |
355 | let file = self.db.file_syntax(file_id); | 307 | let file = self.db.source_file(file_id); |
356 | 308 | ||
357 | Ok(symbol.docs(&file)) | 309 | Ok(symbol.docs(&file)) |
358 | } | 310 | } |
359 | 311 | ||
360 | pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { | 312 | pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { |
361 | let syntax = self.db.file_syntax(file_id); | 313 | let syntax = self.db.source_file(file_id); |
362 | 314 | ||
363 | let mut res = ra_editor::diagnostics(&syntax) | 315 | let mut res = ra_editor::diagnostics(&syntax) |
364 | .into_iter() | 316 | .into_iter() |
@@ -368,7 +320,7 @@ impl AnalysisImpl { | |||
368 | fix: None, | 320 | fix: None, |
369 | }) | 321 | }) |
370 | .collect::<Vec<_>>(); | 322 | .collect::<Vec<_>>(); |
371 | if let Some(m) = ModuleDescriptor::guess_from_file_id(&*self.db, file_id)? { | 323 | if let Some(m) = hir::Module::guess_from_file_id(&*self.db, file_id)? { |
372 | for (name_node, problem) in m.problems(&*self.db) { | 324 | for (name_node, problem) in m.problems(&*self.db) { |
373 | let diag = match problem { | 325 | let diag = match problem { |
374 | Problem::UnresolvedModule { candidate } => { | 326 | Problem::UnresolvedModule { candidate } => { |
@@ -445,8 +397,8 @@ impl AnalysisImpl { | |||
445 | pub fn resolve_callable( | 397 | pub fn resolve_callable( |
446 | &self, | 398 | &self, |
447 | position: FilePosition, | 399 | position: FilePosition, |
448 | ) -> Cancelable<Option<(FnDescriptor, Option<usize>)>> { | 400 | ) -> Cancelable<Option<(FnSignatureInfo, Option<usize>)>> { |
449 | let file = self.db.file_syntax(position.file_id); | 401 | let file = self.db.source_file(position.file_id); |
450 | let syntax = file.syntax(); | 402 | let syntax = file.syntax(); |
451 | 403 | ||
452 | // Find the calling expression and it's NameRef | 404 | // Find the calling expression and it's NameRef |
@@ -455,11 +407,12 @@ impl AnalysisImpl { | |||
455 | 407 | ||
456 | // Resolve the function's NameRef (NOTE: this isn't entirely accurate). | 408 | // Resolve the function's NameRef (NOTE: this isn't entirely accurate). |
457 | let file_symbols = self.index_resolve(name_ref)?; | 409 | let file_symbols = self.index_resolve(name_ref)?; |
458 | for (fn_fiel_id, fs) in file_symbols { | 410 | for (fn_file_id, fs) in file_symbols { |
459 | if fs.kind == FN_DEF { | 411 | if fs.kind == FN_DEF { |
460 | let fn_file = self.db.file_syntax(fn_fiel_id); | 412 | let fn_file = self.db.source_file(fn_file_id); |
461 | if let Some(fn_def) = find_node_at_offset(fn_file.syntax(), fs.node_range.start()) { | 413 | if let Some(fn_def) = find_node_at_offset(fn_file.syntax(), fs.node_range.start()) { |
462 | if let Some(descriptor) = FnDescriptor::new(fn_def) { | 414 | let descr = hir::Function::guess_from_source(&*self.db, fn_file_id, fn_def); |
415 | if let Some(descriptor) = descr.signature_info(&*self.db) { | ||
463 | // If we have a calling expression let's find which argument we are on | 416 | // If we have a calling expression let's find which argument we are on |
464 | let mut current_parameter = None; | 417 | let mut current_parameter = None; |
465 | 418 | ||
@@ -532,16 +485,6 @@ impl SourceChange { | |||
532 | } | 485 | } |
533 | } | 486 | } |
534 | 487 | ||
535 | impl CrateGraph { | ||
536 | fn crate_id_for_crate_root(&self, file_id: FileId) -> Option<CrateId> { | ||
537 | let (&crate_id, _) = self | ||
538 | .crate_roots | ||
539 | .iter() | ||
540 | .find(|(_crate_id, &root_id)| root_id == file_id)?; | ||
541 | Some(crate_id) | ||
542 | } | ||
543 | } | ||
544 | |||
545 | enum FnCallNode<'a> { | 488 | enum FnCallNode<'a> { |
546 | CallExpr(ast::CallExpr<'a>), | 489 | CallExpr(ast::CallExpr<'a>), |
547 | MethodCallExpr(ast::MethodCallExpr<'a>), | 490 | MethodCallExpr(ast::MethodCallExpr<'a>), |
@@ -580,16 +523,3 @@ impl<'a> FnCallNode<'a> { | |||
580 | } | 523 | } |
581 | } | 524 | } |
582 | } | 525 | } |
583 | |||
584 | fn resolve_local_name( | ||
585 | db: &db::RootDatabase, | ||
586 | file_id: FileId, | ||
587 | name_ref: ast::NameRef, | ||
588 | ) -> Option<(SmolStr, TextRange)> { | ||
589 | let fn_def = name_ref.syntax().ancestors().find_map(ast::FnDef::cast)?; | ||
590 | let fn_id = FnId::get(db, file_id, fn_def); | ||
591 | let scopes = db.fn_scopes(fn_id); | ||
592 | let scope_entry = crate::descriptors::function::resolve_local_name(name_ref, &scopes)?; | ||
593 | let syntax = db.resolve_syntax_ptr(scope_entry.ptr().into_global(file_id)); | ||
594 | Some((scope_entry.name().clone(), syntax.range())) | ||
595 | } | ||