From 569ac5bee186e907cc14300ab0d46976ed063580 Mon Sep 17 00:00:00 2001 From: hamidreza kalbasi Date: Wed, 22 Sep 2021 11:37:26 +0330 Subject: [PATCH] use find_definition in go to --- crates/ide/src/goto_definition.rs | 55 +++++++++--------------- crates/ide/src/hover.rs | 71 +++++++++++++++++++------------ crates/ide/src/lib.rs | 2 +- 3 files changed, 64 insertions(+), 64 deletions(-) diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index b2d0fead8790..c2fdc8dc7cd7 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs @@ -1,5 +1,11 @@ use std::{convert::TryInto, iter}; +use crate::hover::find_definition; +use crate::{ + display::{ToNav, TryToNav}, + doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def}, + FilePosition, NavigationTarget, RangeInfo, +}; use either::Either; use hir::{AsAssocItem, InFile, ModuleDef, Semantics}; use ide_db::{ @@ -11,12 +17,6 @@ use ide_db::{ use itertools::Itertools; use syntax::{ast, match_ast, AstNode, AstToken, SyntaxKind::*, SyntaxToken, TextRange, T}; -use crate::{ - display::{ToNav, TryToNav}, - doc_links::{doc_attributes, extract_definitions_from_docs, resolve_doc_path_for_def}, - FilePosition, NavigationTarget, RangeInfo, -}; - // Feature: Go to Definition // // Navigates to the definition of an identifier. @@ -58,39 +58,22 @@ pub(crate) fn goto_definition( .into_iter() .filter_map(|token| { let parent = token.parent()?; - let navs = match_ast! { + let result = find_definition(&sema, &parent) + .flat_map(|def| { + try_find_trait_item_definition(sema.db, &def) + .unwrap_or_else(|| def_to_nav(sema.db, def)) + }) + .collect::>(); + if !result.is_empty() { + return Some(result); + } + match_ast! { match parent { - ast::NameRef(name_ref) => { - reference_definition(&sema, Either::Right(&name_ref)) - }, - ast::Name(name) => { - match NameClass::classify(&sema, &name)? { - NameClass::Definition(def) | NameClass::ConstReference(def) => { - try_find_trait_item_definition(sema.db, &def) - .unwrap_or_else(|| def_to_nav(sema.db, def)) - } - NameClass::PatFieldShorthand { local_def, field_ref } => { - local_and_field_to_nav(sema.db, local_def, field_ref) - }, - } - }, - ast::Lifetime(lt) => { - match NameClass::classify_lifetime(&sema, <) { - Some(name_class) => { - match name_class { - NameClass::Definition(def) => def_to_nav(sema.db, def), - _ => return None, - } - } - None => reference_definition(&sema, Either::Left(<)), - } - }, ast::TokenTree(tt) => - try_lookup_include_path_or_derive(&sema, tt, token, position.file_id)?, - _ => return None, + try_lookup_include_path_or_derive(&sema, tt, token, position.file_id), + _ => None } - }; - Some(navs) + } }) .flatten() .unique() diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 0d916acaded4..a01e272e5354 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs @@ -1,4 +1,4 @@ -use std::{collections::HashSet, ops::ControlFlow}; +use std::{collections::HashSet, iter, ops::ControlFlow}; use either::Either; use hir::{AsAssocItem, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo}; @@ -199,7 +199,7 @@ fn find_hover_result( // so don't add them to the `seen` duplicate check let mut add_to_seen_definitions = true; - let definition = find_definition(sema, node).or_else(|| { + let definition = find_definition(sema, node).next().or_else(|| { // intra-doc links // FIXME: move comment + attribute special cases somewhere else to simplify control flow, // hopefully simplifying the return type of this function in the process @@ -724,34 +724,51 @@ fn definition_mod_path(db: &RootDatabase, def: &Definition) -> Option { def.module(db).map(|module| render_path(db, module, definition_owner_name(db, def))) } -pub(crate) fn find_definition( - sema: &Semantics, +pub(crate) fn find_definition<'a>( + sema: &'a Semantics, node: &SyntaxNode, -) -> Option { - match_ast! { - match node { - ast::Name(name) => NameClass::classify(sema, &name).map(|class| match class { - NameClass::Definition(it) | NameClass::ConstReference(it) => it, - NameClass::PatFieldShorthand { local_def, field_ref: _ } => Definition::Local(local_def), - }), - ast::NameRef(name_ref) => NameRefClass::classify(sema, &name_ref).map(|class| match class { - NameRefClass::Definition(def) => def, - NameRefClass::FieldShorthand { local_ref: _, field_ref } => { - Definition::Field(field_ref) - } - }), - ast::Lifetime(lifetime) => NameClass::classify_lifetime(&sema, &lifetime).map_or_else( - || { - NameRefClass::classify_lifetime(&sema, &lifetime).and_then(|class| match class { - NameRefClass::Definition(it) => Some(it), - _ => None, - }) +) -> impl Iterator + 'a { + iter::once(node.clone()).flat_map(move |node| { + match_ast! { + match node { + ast::Name(name) => { + let class = if let Some(x) = NameClass::classify(&sema, &name) { + x + } else { + return vec![]; + }; + match class { + NameClass::Definition(it) | NameClass::ConstReference(it) => vec![it], + NameClass::PatFieldShorthand { local_def, field_ref } => vec![Definition::Local(local_def), Definition::Field(field_ref)], + } }, - NameClass::defined, - ), - _ => None, + ast::NameRef(name_ref) => { + let class = if let Some(x) = NameRefClass::classify(sema, &name_ref) { + x + } else { + return vec![]; + }; + match class { + NameRefClass::Definition(def) => vec![def], + NameRefClass::FieldShorthand { local_ref, field_ref } => { + vec![Definition::Field(field_ref), Definition::Local(local_ref)] + } + } + }, + ast::Lifetime(lifetime) => { + (if let Some(x) = NameClass::classify_lifetime(&sema, &lifetime) { + NameClass::defined(x) + } else { + NameRefClass::classify_lifetime(&sema, &lifetime).and_then(|class| match class { + NameRefClass::Definition(it) => Some(it), + _ => None, + }) + }).into_iter().collect() + }, + _ => vec![], + } } - } + }) } pub(crate) fn hover_for_definition( diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 21872c81d134..9ea0fe171c36 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs @@ -35,7 +35,7 @@ mod goto_declaration; mod goto_definition; mod goto_implementation; mod goto_type_definition; -mod hover; +pub mod hover; mod inlay_hints; mod join_lines; mod markdown_remove;