about summary refs log tree commit diff
diff options
context:
space:
mode:
authoralibektas <bektasali@protonmail.com>2023-05-14 02:38:03 +0200
committerAli Bektas <bektasali@protonmail.com>2023-05-24 23:57:24 +0200
commit1222869b3eb66f2fc67b6780feb897eddadfdec5 (patch)
treed90e85cb3afaff22c526996167dca0923107ade9
parenta512774fd97ba8645fd7bc123b179f40a76017b2 (diff)
downloadrust-1222869b3eb66f2fc67b6780feb897eddadfdec5.tar.gz
rust-1222869b3eb66f2fc67b6780feb897eddadfdec5.zip
Fix #14557. Docs aliases can now be detected and used in searching for workspace symbols
-rw-r--r--crates/hir/src/symbols.rs98
-rw-r--r--crates/ide-db/src/symbol_index.rs27
-rw-r--r--crates/ide-db/src/test_data/test_doc_alias.txt202
-rw-r--r--crates/ide-db/src/test_data/test_symbol_index_collection.txt22
-rw-r--r--crates/ide/src/goto_definition.rs1
-rw-r--r--crates/ide/src/lib.rs2
-rw-r--r--crates/ide/src/navigation_target.rs13
-rw-r--r--crates/ide/src/runnables.rs16
-rw-r--r--crates/rust-analyzer/src/handlers/request.rs5
9 files changed, 338 insertions, 48 deletions
diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs
index af37206eadc..207e8206c92 100644
--- a/crates/hir/src/symbols.rs
+++ b/crates/hir/src/symbols.rs
@@ -20,6 +20,7 @@ pub struct FileSymbol {
     pub def: ModuleDef,
     pub loc: DeclarationLocation,
     pub container_name: Option<SmolStr>,
+    pub is_alias: bool,
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -249,46 +250,69 @@ impl<'a> SymbolCollector<'a> {
         <L as Lookup>::Data: HasSource,
         <<L as Lookup>::Data as HasSource>::Value: HasName,
     {
-        self.push_file_symbol(|s| {
-            let loc = id.lookup(s.db.upcast());
-            let source = loc.source(s.db.upcast());
-            let name_node = source.value.name()?;
-            Some(FileSymbol {
-                name: name_node.text().into(),
-                def: ModuleDef::from(id.into()),
-                container_name: s.current_container_name.clone(),
-                loc: DeclarationLocation {
-                    hir_file_id: source.file_id,
-                    ptr: SyntaxNodePtr::new(source.value.syntax()),
-                    name_ptr: SyntaxNodePtr::new(name_node.syntax()),
-                },
-            })
-        })
-    }
+        let loc = id.lookup(self.db.upcast());
+        let source = loc.source(self.db.upcast());
+        let Some(name_node) = source.value.name() else { return };
+        let def = ModuleDef::from(id.into());
+        let dec_loc = DeclarationLocation {
+            hir_file_id: source.file_id,
+            ptr: SyntaxNodePtr::new(source.value.syntax()),
+            name_ptr: SyntaxNodePtr::new(name_node.syntax()),
+        };
+
+        if let Some(attrs) = def.attrs(self.db) {
+            for alias in attrs.doc_aliases() {
+                self.symbols.push(FileSymbol {
+                    name: alias,
+                    def,
+                    loc: dec_loc.clone(),
+                    container_name: self.current_container_name.clone(),
+                    is_alias: true,
+                });
+            }
+        }
 
-    fn push_module(&mut self, module_id: ModuleId) {
-        self.push_file_symbol(|s| {
-            let def_map = module_id.def_map(s.db.upcast());
-            let module_data = &def_map[module_id.local_id];
-            let declaration = module_data.origin.declaration()?;
-            let module = declaration.to_node(s.db.upcast());
-            let name_node = module.name()?;
-            Some(FileSymbol {
-                name: name_node.text().into(),
-                def: ModuleDef::Module(module_id.into()),
-                container_name: s.current_container_name.clone(),
-                loc: DeclarationLocation {
-                    hir_file_id: declaration.file_id,
-                    ptr: SyntaxNodePtr::new(module.syntax()),
-                    name_ptr: SyntaxNodePtr::new(name_node.syntax()),
-                },
-            })
-        })
+        self.symbols.push(FileSymbol {
+            name: name_node.text().into(),
+            def,
+            container_name: self.current_container_name.clone(),
+            loc: dec_loc,
+            is_alias: false,
+        });
     }
 
-    fn push_file_symbol(&mut self, f: impl FnOnce(&Self) -> Option<FileSymbol>) {
-        if let Some(file_symbol) = f(self) {
-            self.symbols.push(file_symbol);
+    fn push_module(&mut self, module_id: ModuleId) {
+        let def_map = module_id.def_map(self.db.upcast());
+        let module_data = &def_map[module_id.local_id];
+        let Some(declaration) = module_data.origin.declaration() else { return };
+        let module = declaration.to_node(self.db.upcast());
+        let Some(name_node) = module.name() else { return };
+        let dec_loc = DeclarationLocation {
+            hir_file_id: declaration.file_id,
+            ptr: SyntaxNodePtr::new(module.syntax()),
+            name_ptr: SyntaxNodePtr::new(name_node.syntax()),
+        };
+
+        let def = ModuleDef::Module(module_id.into());
+
+        if let Some(attrs) = def.attrs(self.db) {
+            for alias in attrs.doc_aliases() {
+                self.symbols.push(FileSymbol {
+                    name: alias,
+                    def,
+                    loc: dec_loc.clone(),
+                    container_name: self.current_container_name.clone(),
+                    is_alias: true,
+                });
+            }
         }
+
+        self.symbols.push(FileSymbol {
+            name: name_node.text().into(),
+            def: ModuleDef::Module(module_id.into()),
+            container_name: self.current_container_name.clone(),
+            loc: dec_loc,
+            is_alias: false,
+        });
     }
 }
diff --git a/crates/ide-db/src/symbol_index.rs b/crates/ide-db/src/symbol_index.rs
index fa796ae13b2..b54c43b296b 100644
--- a/crates/ide-db/src/symbol_index.rs
+++ b/crates/ide-db/src/symbol_index.rs
@@ -434,4 +434,31 @@ struct StructInModB;
 
         expect_file!["./test_data/test_symbol_index_collection.txt"].assert_debug_eq(&symbols);
     }
+
+    #[test]
+    fn test_doc_alias() {
+        let (db, _) = RootDatabase::with_single_file(
+            r#"
+#[doc(alias="s1")]
+#[doc(alias="s2")]
+#[doc(alias("mul1","mul2"))]
+struct Struct;
+
+#[doc(alias="s1")]
+struct Duplicate;
+        "#,
+        );
+
+        let symbols: Vec<_> = Crate::from(db.test_crate())
+            .modules(&db)
+            .into_iter()
+            .map(|module_id| {
+                let mut symbols = SymbolCollector::collect_module(&db, module_id);
+                symbols.sort_by_key(|it| it.name.clone());
+                (module_id, symbols)
+            })
+            .collect();
+
+        expect_file!["./test_data/test_doc_alias.txt"].assert_debug_eq(&symbols);
+    }
 }
diff --git a/crates/ide-db/src/test_data/test_doc_alias.txt b/crates/ide-db/src/test_data/test_doc_alias.txt
new file mode 100644
index 00000000000..77714efa350
--- /dev/null
+++ b/crates/ide-db/src/test_data/test_doc_alias.txt
@@ -0,0 +1,202 @@
+[
+    (
+        Module {
+            id: ModuleId {
+                krate: Idx::<CrateData>(0),
+                block: None,
+                local_id: Idx::<ModuleData>(0),
+            },
+        },
+        [
+            FileSymbol {
+                name: "Duplicate",
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                1,
+                            ),
+                        },
+                    ),
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: HirFileId(
+                        0,
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: STRUCT,
+                        range: 83..119,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 109..118,
+                    },
+                },
+                container_name: None,
+                is_alias: false,
+            },
+            FileSymbol {
+                name: "Struct",
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                0,
+                            ),
+                        },
+                    ),
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: HirFileId(
+                        0,
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: STRUCT,
+                        range: 0..81,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 74..80,
+                    },
+                },
+                container_name: None,
+                is_alias: false,
+            },
+            FileSymbol {
+                name: "mul1",
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                0,
+                            ),
+                        },
+                    ),
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: HirFileId(
+                        0,
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: STRUCT,
+                        range: 0..81,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 74..80,
+                    },
+                },
+                container_name: None,
+                is_alias: true,
+            },
+            FileSymbol {
+                name: "mul2",
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                0,
+                            ),
+                        },
+                    ),
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: HirFileId(
+                        0,
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: STRUCT,
+                        range: 0..81,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 74..80,
+                    },
+                },
+                container_name: None,
+                is_alias: true,
+            },
+            FileSymbol {
+                name: "s1",
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                0,
+                            ),
+                        },
+                    ),
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: HirFileId(
+                        0,
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: STRUCT,
+                        range: 0..81,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 74..80,
+                    },
+                },
+                container_name: None,
+                is_alias: true,
+            },
+            FileSymbol {
+                name: "s1",
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                1,
+                            ),
+                        },
+                    ),
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: HirFileId(
+                        0,
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: STRUCT,
+                        range: 83..119,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 109..118,
+                    },
+                },
+                container_name: None,
+                is_alias: true,
+            },
+            FileSymbol {
+                name: "s2",
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                0,
+                            ),
+                        },
+                    ),
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: HirFileId(
+                        0,
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: STRUCT,
+                        range: 0..81,
+                    },
+                    name_ptr: SyntaxNodePtr {
+                        kind: NAME,
+                        range: 74..80,
+                    },
+                },
+                container_name: None,
+                is_alias: true,
+            },
+        ],
+    ),
+]
diff --git a/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/crates/ide-db/src/test_data/test_symbol_index_collection.txt
index 1e34dd633c8..b5adfc13d96 100644
--- a/crates/ide-db/src/test_data/test_symbol_index_collection.txt
+++ b/crates/ide-db/src/test_data/test_symbol_index_collection.txt
@@ -31,6 +31,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "CONST",
@@ -55,6 +56,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "CONST_WITH_INNER",
@@ -79,6 +81,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "Enum",
@@ -105,6 +108,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "Macro",
@@ -131,6 +135,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "STATIC",
@@ -155,6 +160,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "Struct",
@@ -181,6 +187,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "StructFromMacro",
@@ -207,6 +214,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "StructInFn",
@@ -235,6 +243,7 @@
                 container_name: Some(
                     "main",
                 ),
+                is_alias: false,
             },
             FileSymbol {
                 name: "StructInNamedConst",
@@ -263,6 +272,7 @@
                 container_name: Some(
                     "CONST_WITH_INNER",
                 ),
+                is_alias: false,
             },
             FileSymbol {
                 name: "StructInUnnamedConst",
@@ -289,6 +299,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "Trait",
@@ -313,6 +324,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "Union",
@@ -339,6 +351,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "a_mod",
@@ -365,6 +378,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "b_mod",
@@ -391,6 +405,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "define_struct",
@@ -417,6 +432,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "impl_fn",
@@ -441,6 +457,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "macro_rules_macro",
@@ -467,6 +484,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "main",
@@ -491,6 +509,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
             FileSymbol {
                 name: "trait_fn",
@@ -517,6 +536,7 @@
                 container_name: Some(
                     "Trait",
                 ),
+                is_alias: false,
             },
         ],
     ),
@@ -554,6 +574,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
         ],
     ),
@@ -591,6 +612,7 @@
                     },
                 },
                 container_name: None,
+                is_alias: false,
             },
         ],
     ),
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index ef3f14d79d1..4e641357e37 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -113,6 +113,7 @@ fn try_lookup_include_path(
         file_id,
         full_range: TextRange::new(0.into(), size),
         name: path.into(),
+        alias: None,
         focus_range: None,
         kind: None,
         container_name: None,
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 72d20af6637..4e5f01e7166 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -405,7 +405,7 @@ impl Analysis {
         self.with_db(|db| {
             symbol_index::world_symbols(db, query)
                 .into_iter() // xx: should we make this a par iter?
-                .filter_map(|s| s.def.try_to_nav(db))
+                .filter_map(|s| s.try_to_nav(db))
                 .collect::<Vec<_>>()
         })
     }
diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs
index d8ce79de375..65c37ca68c5 100644
--- a/crates/ide/src/navigation_target.rs
+++ b/crates/ide/src/navigation_target.rs
@@ -45,6 +45,9 @@ pub struct NavigationTarget {
     pub container_name: Option<SmolStr>,
     pub description: Option<String>,
     pub docs: Option<Documentation>,
+    /// In addition to a `name` field, a `NavigationTarget` may also be aliased
+    /// In such cases we want a `NavigationTarget` to be accessible by its alias
+    pub alias: Option<SmolStr>,
 }
 
 impl fmt::Debug for NavigationTarget {
@@ -154,6 +157,7 @@ impl NavigationTarget {
             container_name: None,
             description: None,
             docs: None,
+            alias: None,
         }
     }
 }
@@ -165,7 +169,8 @@ impl TryToNav for FileSymbol {
 
         Some(NavigationTarget {
             file_id: full_range.file_id,
-            name: self.name.clone(),
+            name: self.def.name(db)?.to_smol_str(),
+            alias: if self.is_alias { Some(self.name.clone()) } else { None },
             kind: Some(hir::ModuleDefId::from(self.def).into()),
             full_range: full_range.range,
             focus_range: Some(name_range.range),
@@ -466,6 +471,7 @@ impl ToNav for LocalSource {
         NavigationTarget {
             file_id,
             name,
+            alias: None,
             kind: Some(kind),
             full_range,
             focus_range,
@@ -494,6 +500,7 @@ impl ToNav for hir::Label {
         NavigationTarget {
             file_id,
             name,
+            alias: None,
             kind: Some(SymbolKind::Label),
             full_range,
             focus_range,
@@ -534,6 +541,7 @@ impl TryToNav for hir::TypeParam {
         Some(NavigationTarget {
             file_id,
             name,
+            alias: None,
             kind: Some(SymbolKind::TypeParam),
             full_range,
             focus_range,
@@ -560,6 +568,7 @@ impl TryToNav for hir::LifetimeParam {
         Some(NavigationTarget {
             file_id,
             name,
+            alias: None,
             kind: Some(SymbolKind::LifetimeParam),
             full_range,
             focus_range: Some(full_range),
@@ -589,6 +598,7 @@ impl TryToNav for hir::ConstParam {
         Some(NavigationTarget {
             file_id,
             name,
+            alias: None,
             kind: Some(SymbolKind::ConstParam),
             full_range,
             focus_range,
@@ -643,6 +653,7 @@ fn foo() { enum FooInner { } }
                     focus_range: 34..42,
                     name: "FooInner",
                     kind: Enum,
+                    container_name: "foo",
                     description: "enum FooInner",
                 },
             ]
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 64150cc2f7f..ec57c02145e 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -2232,14 +2232,14 @@ mod tests {
                             file_id: FileId(
                                 0,
                             ),
-                            full_range: 52..115,
-                            focus_range: 67..75,
-                            name: "foo_test",
+                            full_range: 121..185,
+                            focus_range: 136..145,
+                            name: "foo2_test",
                             kind: Function,
                         },
                         kind: Test {
                             test_id: Path(
-                                "tests::foo_test",
+                                "tests::foo2_test",
                             ),
                             attr: TestAttr {
                                 ignore: false,
@@ -2253,14 +2253,14 @@ mod tests {
                             file_id: FileId(
                                 0,
                             ),
-                            full_range: 121..185,
-                            focus_range: 136..145,
-                            name: "foo2_test",
+                            full_range: 52..115,
+                            focus_range: 67..75,
+                            name: "foo_test",
                             kind: Function,
                         },
                         kind: Test {
                             test_id: Path(
-                                "tests::foo2_test",
+                                "tests::foo_test",
                             ),
                             attr: TestAttr {
                                 ignore: false,
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs
index 9c198eefc75..c8eda567db7 100644
--- a/crates/rust-analyzer/src/handlers/request.rs
+++ b/crates/rust-analyzer/src/handlers/request.rs
@@ -520,7 +520,10 @@ pub(crate) fn handle_workspace_symbol(
 
             #[allow(deprecated)]
             let info = SymbolInformation {
-                name: nav.name.to_string(),
+                name: match nav.alias {
+                    Some(ref alias) => format!("{} (alias {})", alias, nav.name),
+                    None => format!("{}", nav.name),
+                },
                 kind: nav
                     .kind
                     .map(to_proto::symbol_kind)