about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ide-db/src/defs.rs28
-rw-r--r--crates/ide/src/static_index.rs4
-rw-r--r--crates/rust-analyzer/src/cli/scip.rs13
3 files changed, 40 insertions, 5 deletions
diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs
index ded5d4e3db5..1b9e10e30f5 100644
--- a/crates/ide-db/src/defs.rs
+++ b/crates/ide-db/src/defs.rs
@@ -7,10 +7,10 @@
 
 use arrayvec::ArrayVec;
 use hir::{
-    Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DeriveHelper, DocLinkDef,
-    ExternCrateDecl, Field, Function, GenericParam, HasVisibility, Impl, Label, Local, Macro,
-    Module, ModuleDef, Name, PathResolution, Semantics, Static, ToolModule, Trait, TraitAlias,
-    TypeAlias, Variant, Visibility,
+    Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DefWithBody, DeriveHelper,
+    DocLinkDef, ExternCrateDecl, Field, Function, GenericParam, HasVisibility, Impl, Label, Local,
+    Macro, Module, ModuleDef, Name, PathResolution, Semantics, Static, ToolModule, Trait,
+    TraitAlias, TypeAlias, Variant, Visibility,
 };
 use stdx::impl_from;
 use syntax::{
@@ -83,6 +83,13 @@ impl Definition {
         Some(module)
     }
 
+    pub fn enclosing_definition(&self, db: &RootDatabase) -> Option<Definition> {
+        match self {
+            Definition::Local(it) => it.parent(db).try_into().ok(),
+            _ => None,
+        }
+    }
+
     pub fn visibility(&self, db: &RootDatabase) -> Option<Visibility> {
         let vis = match self {
             Definition::Field(sf) => sf.visibility(db),
@@ -662,3 +669,16 @@ impl From<DocLinkDef> for Definition {
         }
     }
 }
+
+impl TryFrom<DefWithBody> for Definition {
+    type Error = ();
+    fn try_from(def: DefWithBody) -> Result<Self, Self::Error> {
+        match def {
+            DefWithBody::Function(it) => Ok(it.into()),
+            DefWithBody::Static(it) => Ok(it.into()),
+            DefWithBody::Const(it) => Ok(it.into()),
+            DefWithBody::Variant(it) => Ok(it.into()),
+            DefWithBody::InTypeConst(_) => Err(()),
+        }
+    }
+}
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index 52f1a44615f..32b052ba463 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -47,6 +47,7 @@ pub struct TokenStaticData {
     pub references: Vec<ReferenceData>,
     pub moniker: Option<MonikerResult>,
     pub display_name: Option<String>,
+    pub enclosing_moniker: Option<MonikerResult>,
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -174,6 +175,9 @@ impl StaticIndex<'_> {
                     references: vec![],
                     moniker: current_crate.and_then(|cc| def_to_moniker(self.db, def, cc)),
                     display_name: def.name(self.db).map(|name| name.display(self.db).to_string()),
+                    enclosing_moniker: current_crate
+                        .zip(def.enclosing_definition(self.db))
+                        .and_then(|(cc, enclosing_def)| def_to_moniker(self.db, enclosing_def, cc)),
                 });
                 self.def_map.insert(def, it);
                 it
diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs
index 02f341c9bd4..fd882ef1d9b 100644
--- a/crates/rust-analyzer/src/cli/scip.rs
+++ b/crates/rust-analyzer/src/cli/scip.rs
@@ -78,6 +78,7 @@ impl flags::Scip {
 
         let mut symbols_emitted: HashSet<TokenId> = HashSet::default();
         let mut tokens_to_symbol: HashMap<TokenId, String> = HashMap::new();
+        let mut tokens_to_enclosing_symbol: HashMap<TokenId, Option<String>> = HashMap::new();
 
         for StaticIndexedFile { file_id, tokens, .. } in si.files {
             let mut local_count = 0;
@@ -117,6 +118,16 @@ impl flags::Scip {
                         scip::symbol::format_symbol(symbol)
                     })
                     .clone();
+                let enclosing_symbol = tokens_to_enclosing_symbol
+                    .entry(id)
+                    .or_insert_with(|| {
+                        token
+                            .enclosing_moniker
+                            .as_ref()
+                            .map(moniker_to_symbol)
+                            .map(scip::symbol::format_symbol)
+                    })
+                    .clone();
 
                 let mut symbol_roles = Default::default();
 
@@ -140,7 +151,7 @@ impl flags::Scip {
                             kind: Default::default(),
                             display_name: token.display_name.clone().unwrap_or_default(),
                             signature_documentation: Default::default(),
-                            enclosing_symbol: String::new(),
+                            enclosing_symbol: enclosing_symbol.unwrap_or_default(),
                         };
 
                         symbols.push(symbol_info)