diff options
Diffstat (limited to 'crates/ra_ide/src/goto_type_definition.rs')
-rw-r--r-- | crates/ra_ide/src/goto_type_definition.rs | 36 |
1 files changed, 18 insertions, 18 deletions
diff --git a/crates/ra_ide/src/goto_type_definition.rs b/crates/ra_ide/src/goto_type_definition.rs index 69940fc36..869a4708b 100644 --- a/crates/ra_ide/src/goto_type_definition.rs +++ b/crates/ra_ide/src/goto_type_definition.rs | |||
@@ -1,31 +1,31 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::db::AstDatabase; | ||
4 | use ra_ide_db::RootDatabase; | 3 | use ra_ide_db::RootDatabase; |
5 | use ra_syntax::{ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset}; | 4 | use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset}; |
6 | 5 | ||
7 | use crate::{ | 6 | use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo}; |
8 | display::ToNav, expand::descend_into_macros, FilePosition, NavigationTarget, RangeInfo, | ||
9 | }; | ||
10 | 7 | ||
11 | pub(crate) fn goto_type_definition( | 8 | pub(crate) fn goto_type_definition( |
12 | db: &RootDatabase, | 9 | db: &RootDatabase, |
13 | position: FilePosition, | 10 | position: FilePosition, |
14 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { | 11 | ) -> Option<RangeInfo<Vec<NavigationTarget>>> { |
15 | let file = db.parse_or_expand(position.file_id.into())?; | 12 | let sema = hir::Semantics::new(db); |
16 | let token = pick_best(file.token_at_offset(position.offset))?; | 13 | |
17 | let token = descend_into_macros(db, position.file_id, token); | 14 | let file: ast::SourceFile = sema.parse(position.file_id); |
18 | 15 | let token: SyntaxToken = pick_best(file.syntax().token_at_offset(position.offset))?; | |
19 | let node = token | 16 | let token: SyntaxToken = sema.descend_into_macros(token); |
20 | .value | 17 | |
21 | .ancestors() | 18 | let (ty, node) = sema.ancestors_with_macros(token.parent()).find_map(|node| { |
22 | .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?; | 19 | let ty = match_ast! { |
23 | 20 | match node { | |
24 | let analyzer = hir::SourceAnalyzer::new(db, token.with_value(&node), None); | 21 | ast::Expr(expr) => { sema.type_of_expr(&expr)? }, |
22 | ast::Pat(pat) => { sema.type_of_pat(&pat)? }, | ||
23 | _ => { return None }, | ||
24 | } | ||
25 | }; | ||
25 | 26 | ||
26 | let ty: hir::Type = ast::Expr::cast(node.clone()) | 27 | Some((ty, node)) |
27 | .and_then(|e| analyzer.type_of(db, &e)) | 28 | })?; |
28 | .or_else(|| ast::Pat::cast(node.clone()).and_then(|p| analyzer.type_of_pat(db, &p)))?; | ||
29 | 29 | ||
30 | let adt_def = ty.autoderef(db).find_map(|ty| ty.as_adt())?; | 30 | let adt_def = ty.autoderef(db).find_map(|ty| ty.as_adt())?; |
31 | 31 | ||