]> git.lizzy.rs Git - rust.git/blobdiff - crates/ra_ide_api/src/navigation_target.rs
Rename Type => TypeAlias
[rust.git] / crates / ra_ide_api / src / navigation_target.rs
index d73d4afa72153bd8f73c974bf51db889e1f02da4..6538081ac6b68bfb56bb1f98c9521a91af055853 100644 (file)
@@ -1,9 +1,9 @@
 use ra_db::FileId;
 use ra_syntax::{
-    SyntaxNode, AstNode, SmolStr, TextRange, ast,
+    SyntaxNode, SyntaxNodePtr, AstNode, SmolStr, TextRange, ast,
     SyntaxKind::{self, NAME},
 };
-use hir::{ModuleSource, FieldSource};
+use hir::{ModuleSource, FieldSource, Name};
 
 use crate::{FileSymbol, db::RootDatabase};
 
@@ -19,13 +19,24 @@ pub struct NavigationTarget {
     kind: SyntaxKind,
     full_range: TextRange,
     focus_range: Option<TextRange>,
+    container_name: Option<SmolStr>,
 }
 
 impl NavigationTarget {
+    /// When `focus_range` is specified, returns it. otherwise
+    /// returns `full_range`
+    pub fn range(&self) -> TextRange {
+        self.focus_range.unwrap_or(self.full_range)
+    }
+
     pub fn name(&self) -> &SmolStr {
         &self.name
     }
 
+    pub fn container_name(&self) -> Option<&SmolStr> {
+        self.container_name.as_ref()
+    }
+
     pub fn kind(&self) -> SyntaxKind {
         self.kind
     }
@@ -38,43 +49,48 @@ pub fn full_range(&self) -> TextRange {
         self.full_range
     }
 
-    /// A "most interesting" range withing the `range_full`.
+    /// A "most interesting" range withing the `full_range`.
     ///
-    /// Typically, `range` is the whole syntax node, including doc comments, and
-    /// `focus_range` is the range of the identifier.
+    /// Typically, `full_range` is the whole syntax node,
+    /// including doc comments, and `focus_range` is the range of the identifier.
     pub fn focus_range(&self) -> Option<TextRange> {
         self.focus_range
     }
 
+    pub(crate) fn from_bind_pat(file_id: FileId, pat: &ast::BindPat) -> NavigationTarget {
+        NavigationTarget::from_named(file_id, pat)
+    }
+
     pub(crate) fn from_symbol(symbol: FileSymbol) -> NavigationTarget {
         NavigationTarget {
             file_id: symbol.file_id,
             name: symbol.name.clone(),
             kind: symbol.ptr.kind(),
             full_range: symbol.ptr.range(),
-            focus_range: None,
+            focus_range: symbol.name_range,
+            container_name: symbol.container_name.clone(),
         }
     }
 
     pub(crate) fn from_scope_entry(
         file_id: FileId,
-        entry: &hir::ScopeEntryWithSyntax,
+        name: Name,
+        ptr: SyntaxNodePtr,
     ) -> NavigationTarget {
         NavigationTarget {
             file_id,
-            name: entry.name().to_string().into(),
-            full_range: entry.ptr().range(),
+            name: name.to_string().into(),
+            full_range: ptr.range(),
             focus_range: None,
             kind: NAME,
+            container_name: None,
         }
     }
 
     pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
         let (file_id, source) = module.definition_source(db);
-        let name = module
-            .name(db)
-            .map(|it| it.to_string().into())
-            .unwrap_or_default();
+        let file_id = file_id.as_original_file();
+        let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
         match source {
             ModuleSource::SourceFile(node) => {
                 NavigationTarget::from_syntax(file_id, name, None, node.syntax())
@@ -86,11 +102,9 @@ pub(crate) fn from_module(db: &RootDatabase, module: hir::Module) -> NavigationT
     }
 
     pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> NavigationTarget {
-        let name = module
-            .name(db)
-            .map(|it| it.to_string().into())
-            .unwrap_or_default();
+        let name = module.name(db).map(|it| it.to_string().into()).unwrap_or_default();
         if let Some((file_id, source)) = module.declaration_source(db) {
+            let file_id = file_id.as_original_file();
             return NavigationTarget::from_syntax(file_id, name, None, source.syntax());
         }
         NavigationTarget::from_module(db, module)
@@ -140,13 +154,26 @@ pub(crate) fn from_def(db: &RootDatabase, module_def: hir::ModuleDef) -> Navigat
                 let (file_id, node) = e.source(db);
                 NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
-            hir::ModuleDef::Type(e) => {
+            hir::ModuleDef::TypeAlias(e) => {
                 let (file_id, node) = e.source(db);
                 NavigationTarget::from_named(file_id.original_file(db), &*node)
             }
         }
     }
 
+    pub(crate) fn from_impl_block(
+        db: &RootDatabase,
+        impl_block: hir::ImplBlock,
+    ) -> NavigationTarget {
+        let (file_id, node) = impl_block.source(db);
+        NavigationTarget::from_syntax(
+            file_id.as_original_file(),
+            "impl".into(),
+            None,
+            node.syntax(),
+        )
+    }
+
     #[cfg(test)]
     pub(crate) fn assert_match(&self, expected: &str) {
         let actual = self.debug_render();
@@ -165,10 +192,14 @@ pub(crate) fn debug_render(&self) -> String {
         if let Some(focus_range) = self.focus_range() {
             buf.push_str(&format!(" {:?}", focus_range))
         }
+        if let Some(container_name) = self.container_name() {
+            buf.push_str(&format!(" {}", container_name))
+        }
         buf
     }
 
-    fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget {
+    /// Allows `NavigationTarget` to be created from a `NameOwner`
+    pub(crate) fn from_named(file_id: FileId, node: &impl ast::NameOwner) -> NavigationTarget {
         let name = node.name().map(|it| it.text().clone()).unwrap_or_default();
         let focus_range = node.name().map(|it| it.syntax().range());
         NavigationTarget::from_syntax(file_id, name, focus_range, node.syntax())
@@ -187,6 +218,7 @@ fn from_syntax(
             full_range: node.range(),
             focus_range,
             // ptr: Some(LocalSyntaxPtr::new(node)),
+            container_name: None,
         }
     }
 }