use crate::{
db::RootDatabase,
display::ShortLabel,
- name_ref_kind::{classify_name_ref, NameKind::*},
+ name_kind::{classify_name_ref, NameKind::*},
FilePosition, NavigationTarget, RangeInfo,
};
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![]),
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,
};
let mut no_fallback = false;
match classify_name_ref(db, &analyzer, &name_ref) {
- Some(Method(it)) => 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))));
mod status;
mod completion;
mod runnables;
-mod name_ref_kind;
+mod name_kind;
mod goto_definition;
mod goto_type_definition;
mod extend_selection;
--- /dev/null
+//! 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<ast::BindPat>),
+ SelfParam(AstPtr<ast::SelfParam>),
+ GenericParam(u32),
+}
+
+pub(crate) fn classify_name_ref(
+ db: &RootDatabase,
+ analyzer: &hir::SourceAnalyzer,
+ name_ref: &ast::NameRef,
+) -> Option<NameKind> {
+ 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<NameKind> {
+ 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
+}
+++ /dev/null
-//! 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<ast::BindPat>),
- SelfParam(AstPtr<ast::SelfParam>),
- GenericParam(u32),
-}
-
-pub(crate) fn classify_name_ref(
- db: &RootDatabase,
- analyzer: &hir::SourceAnalyzer,
- name_ref: &ast::NameRef,
-) -> Option<NameKind> {
- 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
-}
//! 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,
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),
}
}
-fn classify_name(db: &RootDatabase, file_id: FileId, name: &ast::Name) -> Option<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
-}
-
pub(crate) fn rename(
db: &RootDatabase,
position: FilePosition,
use crate::{
db::RootDatabase,
- name_ref_kind::{classify_name_ref, NameKind::*},
+ name_kind::{classify_name_ref, NameKind::*},
FileId,
};
// FIXME: try to reuse the SourceAnalyzers
let analyzer = hir::SourceAnalyzer::new(db, file_id, name_ref.syntax(), None);
match classify_name_ref(db, &analyzer, &name_ref) {
- Some(Method(_)) => "function",
Some(Macro(_)) => "macro",
Some(FieldAccess(_)) => "field",
Some(AssocItem(hir::AssocItem::Function(_))) => "function",