From d6ae1b5f0f3e1b9b7f85dcdbd98e0c336b7a882d Mon Sep 17 00:00:00 2001 From: Ekaterina Babshukova Date: Sat, 21 Sep 2019 19:35:39 +0300 Subject: refactor name_ref_kind.rs --- crates/ra_ide_api/src/goto_definition.rs | 3 +- crates/ra_ide_api/src/hover.rs | 3 +- crates/ra_ide_api/src/lib.rs | 2 +- crates/ra_ide_api/src/name_kind.rs | 137 +++++++++++++++++++++++++++ crates/ra_ide_api/src/name_ref_kind.rs | 98 ------------------- crates/ra_ide_api/src/references.rs | 47 +-------- crates/ra_ide_api/src/syntax_highlighting.rs | 3 +- 7 files changed, 145 insertions(+), 148 deletions(-) create mode 100644 crates/ra_ide_api/src/name_kind.rs delete mode 100644 crates/ra_ide_api/src/name_ref_kind.rs diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 13e42bb35..7626a3fd1 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -10,7 +10,7 @@ use ra_syntax::{ use crate::{ db::RootDatabase, display::ShortLabel, - name_ref_kind::{classify_name_ref, NameKind::*}, + name_kind::{classify_name_ref, NameKind::*}, FilePosition, NavigationTarget, RangeInfo, }; @@ -60,7 +60,6 @@ pub(crate) fn reference_definition( Some(Macro(mac)) => return Exact(NavigationTarget::from_macro_def(db, mac)), Some(FieldAccess(field)) => return Exact(NavigationTarget::from_field(db, field)), Some(AssocItem(assoc)) => return Exact(NavigationTarget::from_assoc_item(db, assoc)), - Some(Method(func)) => return Exact(NavigationTarget::from_def_source(db, func)), Some(Def(def)) => match NavigationTarget::from_def(db, def) { Some(nav) => return Exact(nav), None => return Approximate(vec![]), diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 5c2549dc3..170278904 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -14,7 +14,7 @@ use crate::{ description_from_symbol, docs_from_symbol, macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel, }, - name_ref_kind::{classify_name_ref, NameKind::*}, + name_kind::{classify_name_ref, NameKind::*}, FilePosition, FileRange, RangeInfo, }; @@ -104,7 +104,6 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option res.extend(from_def_source(db, it)), Some(Macro(it)) => { let src = it.source(db); res.extend(hover_text(src.ast.doc_comment_text(), Some(macro_label(&src.ast)))); diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index f7fd42f65..cbf79ce03 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs @@ -19,7 +19,7 @@ mod feature_flags; mod status; mod completion; mod runnables; -mod name_ref_kind; +mod name_kind; mod goto_definition; mod goto_type_definition; mod extend_selection; diff --git a/crates/ra_ide_api/src/name_kind.rs b/crates/ra_ide_api/src/name_kind.rs new file mode 100644 index 000000000..64adb1784 --- /dev/null +++ b/crates/ra_ide_api/src/name_kind.rs @@ -0,0 +1,137 @@ +//! FIXME: write short doc here + +use hir::{Either, FromSource}; +use ra_db::FileId; +use ra_syntax::{ast, AstNode, AstPtr}; +use test_utils::tested_by; + +use crate::db::RootDatabase; + +pub enum NameKind { + Macro(hir::MacroDef), + FieldAccess(hir::StructField), + AssocItem(hir::AssocItem), + Def(hir::ModuleDef), + SelfType(hir::Ty), + Pat(AstPtr), + SelfParam(AstPtr), + GenericParam(u32), +} + +pub(crate) fn classify_name_ref( + db: &RootDatabase, + analyzer: &hir::SourceAnalyzer, + name_ref: &ast::NameRef, +) -> Option { + use NameKind::*; + + // Check if it is a method + if let Some(method_call) = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast) { + tested_by!(goto_definition_works_for_methods); + if let Some(func) = analyzer.resolve_method_call(&method_call) { + return Some(AssocItem(func.into())); + } + } + + // It could be a macro call + if let Some(macro_call) = name_ref + .syntax() + .parent() + .and_then(|node| node.parent()) + .and_then(|node| node.parent()) + .and_then(ast::MacroCall::cast) + { + tested_by!(goto_definition_works_for_macros); + if let Some(mac) = analyzer.resolve_macro_call(db, ¯o_call) { + return Some(Macro(mac)); + } + } + + // It could also be a field access + if let Some(field_expr) = name_ref.syntax().parent().and_then(ast::FieldExpr::cast) { + tested_by!(goto_definition_works_for_fields); + if let Some(field) = analyzer.resolve_field(&field_expr) { + return Some(FieldAccess(field)); + }; + } + + // It could also be a named field + if let Some(field_expr) = name_ref.syntax().parent().and_then(ast::RecordField::cast) { + tested_by!(goto_definition_works_for_record_fields); + + if let Some(record_lit) = field_expr.syntax().ancestors().find_map(ast::RecordLit::cast) { + let variant_def = analyzer.resolve_record_literal(&record_lit)?; + let hir_path = hir::Path::from_name_ref(name_ref); + let hir_name = hir_path.as_ident()?; + let field = variant_def.field(db, hir_name)?; + return Some(FieldAccess(field)); + } + } + + // General case, a path or a local: + if let Some(path) = name_ref.syntax().ancestors().find_map(ast::Path::cast) { + if let Some(resolved) = analyzer.resolve_path(db, &path) { + return match resolved { + hir::PathResolution::Def(def) => Some(Def(def)), + hir::PathResolution::LocalBinding(Either::A(pat)) => Some(Pat(pat)), + hir::PathResolution::LocalBinding(Either::B(par)) => Some(SelfParam(par)), + hir::PathResolution::GenericParam(par) => { + // FIXME: get generic param def + Some(GenericParam(par)) + } + hir::PathResolution::Macro(def) => Some(Macro(def)), + hir::PathResolution::SelfType(impl_block) => { + let ty = impl_block.target_ty(db); + Some(SelfType(ty)) + } + hir::PathResolution::AssocItem(assoc) => Some(AssocItem(assoc)), + }; + } + } + + None +} + +pub(crate) fn classify_name( + db: &RootDatabase, + file_id: FileId, + name: &ast::Name, +) -> Option { + use NameKind::*; + + let parent = name.syntax().parent()?; + let file_id = file_id.into(); + + if let Some(pat) = ast::BindPat::cast(parent.clone()) { + return Some(Pat(AstPtr::new(&pat))); + } + if let Some(var) = ast::EnumVariant::cast(parent.clone()) { + let src = hir::Source { file_id, ast: var }; + let var = hir::EnumVariant::from_source(db, src)?; + return Some(Def(var.into())); + } + if let Some(field) = ast::RecordFieldDef::cast(parent.clone()) { + let src = hir::Source { file_id, ast: hir::FieldSource::Named(field) }; + let field = hir::StructField::from_source(db, src)?; + return Some(FieldAccess(field)); + } + if let Some(field) = ast::TupleFieldDef::cast(parent.clone()) { + let src = hir::Source { file_id, ast: hir::FieldSource::Pos(field) }; + let field = hir::StructField::from_source(db, src)?; + return Some(FieldAccess(field)); + } + if let Some(_) = parent.parent().and_then(ast::ItemList::cast) { + let ast = ast::ImplItem::cast(parent.clone())?; + let src = hir::Source { file_id, ast }; + let item = hir::AssocItem::from_source(db, src)?; + return Some(AssocItem(item)); + } + if let Some(item) = ast::ModuleItem::cast(parent.clone()) { + let src = hir::Source { file_id, ast: item }; + let def = hir::ModuleDef::from_source(db, src)?; + return Some(Def(def)); + } + // FIXME: TYPE_PARAM, ALIAS, MACRO_CALL; Union + + None +} diff --git a/crates/ra_ide_api/src/name_ref_kind.rs b/crates/ra_ide_api/src/name_ref_kind.rs deleted file mode 100644 index eb8caabfe..000000000 --- a/crates/ra_ide_api/src/name_ref_kind.rs +++ /dev/null @@ -1,98 +0,0 @@ -//! FIXME: write short doc here - -use hir::Either; -use ra_syntax::{ast, AstNode, AstPtr}; -use test_utils::tested_by; - -use crate::db::RootDatabase; - -pub enum NameKind { - Method(hir::Function), - Macro(hir::MacroDef), - FieldAccess(hir::StructField), - AssocItem(hir::AssocItem), - Def(hir::ModuleDef), - SelfType(hir::Ty), - Pat(AstPtr), - SelfParam(AstPtr), - GenericParam(u32), -} - -pub(crate) fn classify_name_ref( - db: &RootDatabase, - analyzer: &hir::SourceAnalyzer, - name_ref: &ast::NameRef, -) -> Option { - use NameKind::*; - - // Check if it is a method - if let Some(method_call) = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast) { - tested_by!(goto_definition_works_for_methods); - if let Some(func) = analyzer.resolve_method_call(&method_call) { - return Some(Method(func)); - } - } - - // It could be a macro call - if let Some(macro_call) = name_ref - .syntax() - .parent() - .and_then(|node| node.parent()) - .and_then(|node| node.parent()) - .and_then(ast::MacroCall::cast) - { - tested_by!(goto_definition_works_for_macros); - if let Some(mac) = analyzer.resolve_macro_call(db, ¯o_call) { - return Some(Macro(mac)); - } - } - - // It could also be a field access - if let Some(field_expr) = name_ref.syntax().parent().and_then(ast::FieldExpr::cast) { - tested_by!(goto_definition_works_for_fields); - if let Some(field) = analyzer.resolve_field(&field_expr) { - return Some(FieldAccess(field)); - }; - } - - // It could also be a named field - if let Some(field_expr) = name_ref.syntax().parent().and_then(ast::RecordField::cast) { - tested_by!(goto_definition_works_for_record_fields); - - let record_lit = field_expr.syntax().ancestors().find_map(ast::RecordLit::cast); - - if let Some(ty) = record_lit.and_then(|lit| analyzer.type_of(db, &lit.into())) { - if let Some((hir::Adt::Struct(s), _)) = ty.as_adt() { - let hir_path = hir::Path::from_name_ref(name_ref); - let hir_name = hir_path.as_ident().unwrap(); - - if let Some(field) = s.field(db, hir_name) { - return Some(FieldAccess(field)); - } - } - } - } - - // General case, a path or a local: - if let Some(path) = name_ref.syntax().ancestors().find_map(ast::Path::cast) { - if let Some(resolved) = analyzer.resolve_path(db, &path) { - return match resolved { - hir::PathResolution::Def(def) => Some(Def(def)), - hir::PathResolution::LocalBinding(Either::A(pat)) => Some(Pat(pat)), - hir::PathResolution::LocalBinding(Either::B(par)) => Some(SelfParam(par)), - hir::PathResolution::GenericParam(par) => { - // FIXME: get generic param def - Some(GenericParam(par)) - } - hir::PathResolution::Macro(def) => Some(Macro(def)), - hir::PathResolution::SelfType(impl_block) => { - let ty = impl_block.target_ty(db); - Some(SelfType(ty)) - } - hir::PathResolution::AssocItem(assoc) => Some(AssocItem(assoc)), - }; - } - } - - None -} diff --git a/crates/ra_ide_api/src/references.rs b/crates/ra_ide_api/src/references.rs index 9335bc8ca..6a8407c51 100644 --- a/crates/ra_ide_api/src/references.rs +++ b/crates/ra_ide_api/src/references.rs @@ -1,14 +1,14 @@ //! FIXME: write short doc here -use hir::{FromSource, ModuleSource}; +use hir::ModuleSource; use ra_db::{SourceDatabase, SourceDatabaseExt}; -use ra_syntax::{algo::find_node_at_offset, ast, AstNode, AstPtr, SyntaxNode}; +use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNode}; use relative_path::{RelativePath, RelativePathBuf}; use crate::{ db::RootDatabase, - name_ref_kind::{ - classify_name_ref, + name_kind::{ + classify_name, classify_name_ref, NameKind::{self, *}, }, FileId, FilePosition, FileRange, FileSystemEdit, NavigationTarget, RangeInfo, SourceChange, @@ -64,7 +64,6 @@ pub(crate) fn find_all_refs( Macro(mac) => NavigationTarget::from_macro_def(db, mac), FieldAccess(field) => NavigationTarget::from_field(db, field), AssocItem(assoc) => NavigationTarget::from_assoc_item(db, assoc), - Method(func) => NavigationTarget::from_def_source(db, func), Def(def) => NavigationTarget::from_def(db, def)?, SelfType(ref ty) => match ty.as_adt() { Some((def_id, _)) => NavigationTarget::from_adt_def(db, def_id), @@ -105,44 +104,6 @@ pub(crate) fn find_all_refs( } } -fn classify_name(db: &RootDatabase, file_id: FileId, name: &ast::Name) -> Option { - let parent = name.syntax().parent()?; - let file_id = file_id.into(); - - if let Some(pat) = ast::BindPat::cast(parent.clone()) { - return Some(Pat(AstPtr::new(&pat))); - } - if let Some(var) = ast::EnumVariant::cast(parent.clone()) { - let src = hir::Source { file_id, ast: var }; - let var = hir::EnumVariant::from_source(db, src)?; - return Some(Def(var.into())); - } - if let Some(field) = ast::RecordFieldDef::cast(parent.clone()) { - let src = hir::Source { file_id, ast: hir::FieldSource::Named(field) }; - let field = hir::StructField::from_source(db, src)?; - return Some(FieldAccess(field)); - } - if let Some(field) = ast::TupleFieldDef::cast(parent.clone()) { - let src = hir::Source { file_id, ast: hir::FieldSource::Pos(field) }; - let field = hir::StructField::from_source(db, src)?; - return Some(FieldAccess(field)); - } - if let Some(_) = parent.parent().and_then(ast::ItemList::cast) { - let ast = ast::ImplItem::cast(parent.clone())?; - let src = hir::Source { file_id, ast }; - let item = hir::AssocItem::from_source(db, src)?; - return Some(AssocItem(item)); - } - if let Some(item) = ast::ModuleItem::cast(parent.clone()) { - let src = hir::Source { file_id, ast: item }; - let def = hir::ModuleDef::from_source(db, src)?; - return Some(Def(def)); - } - // FIXME: TYPE_PARAM, ALIAS, MACRO_CALL; Union - - None -} - pub(crate) fn rename( db: &RootDatabase, position: FilePosition, diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index 03104e348..98373a49c 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs @@ -14,7 +14,7 @@ use ra_syntax::{ use crate::{ db::RootDatabase, - name_ref_kind::{classify_name_ref, NameKind::*}, + name_kind::{classify_name_ref, NameKind::*}, FileId, }; @@ -104,7 +104,6 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec "function", Some(Macro(_)) => "macro", Some(FieldAccess(_)) => "field", Some(AssocItem(hir::AssocItem::Function(_))) => "function", -- cgit v1.2.3