From c3a4c4429de83450654795534e64e878a774a088 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 18 Feb 2020 18:35:10 +0100 Subject: Refactor primary IDE API This introduces the new type -- Semantics. Semantics maps SyntaxNodes to various semantic info, such as type, name resolution or macro expansions. To do so, Semantics maintains a HashMap which maps every node it saw to the file from which the node originated. This is enough to get all the necessary hir bits just from syntax. --- crates/ra_ide/src/goto_type_definition.rs | 36 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'crates/ra_ide/src/goto_type_definition.rs') 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 @@ //! FIXME: write short doc here -use hir::db::AstDatabase; use ra_ide_db::RootDatabase; -use ra_syntax::{ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset}; +use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset}; -use crate::{ - display::ToNav, expand::descend_into_macros, FilePosition, NavigationTarget, RangeInfo, -}; +use crate::{display::ToNav, FilePosition, NavigationTarget, RangeInfo}; pub(crate) fn goto_type_definition( db: &RootDatabase, position: FilePosition, ) -> Option>> { - let file = db.parse_or_expand(position.file_id.into())?; - let token = pick_best(file.token_at_offset(position.offset))?; - let token = descend_into_macros(db, position.file_id, token); - - let node = token - .value - .ancestors() - .find(|n| ast::Expr::cast(n.clone()).is_some() || ast::Pat::cast(n.clone()).is_some())?; - - let analyzer = hir::SourceAnalyzer::new(db, token.with_value(&node), None); + let sema = hir::Semantics::new(db); + + let file: ast::SourceFile = sema.parse(position.file_id); + let token: SyntaxToken = pick_best(file.syntax().token_at_offset(position.offset))?; + let token: SyntaxToken = sema.descend_into_macros(token); + + let (ty, node) = sema.ancestors_with_macros(token.parent()).find_map(|node| { + let ty = match_ast! { + match node { + ast::Expr(expr) => { sema.type_of_expr(&expr)? }, + ast::Pat(pat) => { sema.type_of_pat(&pat)? }, + _ => { return None }, + } + }; - let ty: hir::Type = ast::Expr::cast(node.clone()) - .and_then(|e| analyzer.type_of(db, &e)) - .or_else(|| ast::Pat::cast(node.clone()).and_then(|p| analyzer.type_of_pat(db, &p)))?; + Some((ty, node)) + })?; let adt_def = ty.autoderef(db).find_map(|ty| ty.as_adt())?; -- cgit v1.2.3