Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide/src/static_index.rs23
-rw-r--r--crates/rust-analyzer/src/cli/scip.rs31
2 files changed, 44 insertions, 10 deletions
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index dee5afbf8d..5feaf21aa9 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -1,14 +1,16 @@
//! This module provides `StaticIndex` which is used for powering
//! read-only code browsers and emitting LSIF
-use hir::{db::HirDatabase, Crate, HirFileIdExt, Module};
+use hir::{db::HirDatabase, Crate, HirFileIdExt, Module, Semantics};
use ide_db::{
base_db::{FileId, FileRange, SourceDatabaseExt},
defs::Definition,
+ documentation::Documentation,
+ famous_defs::FamousDefs,
helpers::get_definition,
FxHashMap, FxHashSet, RootDatabase,
};
-use syntax::{AstNode, SyntaxKind::*, TextRange, T};
+use syntax::{AstNode, SyntaxKind::*, SyntaxNode, TextRange, T};
use crate::inlay_hints::InlayFieldsToResolve;
use crate::navigation_target::UpmappingResult;
@@ -22,7 +24,7 @@ use crate::{
/// A static representation of fully analyzed source code.
///
-/// The intended use-case is powering read-only code browsers and emitting LSIF
+/// The intended use-case is powering read-only code browsers and emitting LSIF/SCIP.
#[derive(Debug)]
pub struct StaticIndex<'a> {
pub files: Vec<StaticIndexedFile>,
@@ -40,6 +42,7 @@ pub struct ReferenceData {
#[derive(Debug)]
pub struct TokenStaticData {
+ pub documentation: Option<Documentation>,
pub hover: Option<HoverResult>,
pub definition: Option<FileRange>,
pub references: Vec<ReferenceData>,
@@ -103,6 +106,19 @@ fn all_modules(db: &dyn HirDatabase) -> Vec<Module> {
modules
}
+fn documentation_for_definition(
+ sema: &Semantics<'_, RootDatabase>,
+ def: Definition,
+ scope_node: &SyntaxNode,
+) -> Option<Documentation> {
+ let famous_defs = match &def {
+ Definition::BuiltinType(_) => Some(FamousDefs(sema, sema.scope(scope_node)?.krate())),
+ _ => None,
+ };
+
+ def.docs(sema.db, famous_defs.as_ref())
+}
+
impl StaticIndex<'_> {
fn add_file(&mut self, file_id: FileId) {
let current_crate = crates_for(self.db, file_id).pop().map(Into::into);
@@ -169,6 +185,7 @@ impl StaticIndex<'_> {
*it
} else {
let it = self.tokens.insert(TokenStaticData {
+ documentation: documentation_for_definition(&sema, def, &node),
hover: hover_for_definition(&sema, file_id, def, &node, &hover_config),
definition: def.try_to_nav(self.db).map(UpmappingResult::call_site).map(|it| {
FileRange { file_id: it.file_id, range: it.focus_or_full_range() }
diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs
index f4aec28834..2d56830c87 100644
--- a/crates/rust-analyzer/src/cli/scip.rs
+++ b/crates/rust-analyzer/src/cli/scip.rs
@@ -135,12 +135,11 @@ impl flags::Scip {
}
if symbols_emitted.insert(id) {
- let documentation = token
- .hover
- .as_ref()
- .map(|hover| hover.markup.as_str())
- .filter(|it| !it.is_empty())
- .map(|it| vec![it.to_owned()]);
+ let documentation = match &token.documentation {
+ Some(doc) => vec![doc.as_str().to_owned()],
+ None => vec![],
+ };
+
let position_encoding =
scip_types::PositionEncoding::UTF8CodeUnitOffsetFromLineStart.into();
let signature_documentation =
@@ -153,7 +152,7 @@ impl flags::Scip {
});
let symbol_info = scip_types::SymbolInformation {
symbol: symbol.clone(),
- documentation: documentation.unwrap_or_default(),
+ documentation,
relationships: Vec::new(),
special_fields: Default::default(),
kind: symbol_kind(token.kind).into(),
@@ -599,4 +598,22 @@ pub mod example_mod {
"rust-analyzer cargo main . MyTypeAlias#",
);
}
+
+ #[test]
+ fn documentation_matches_doc_comment() {
+ let s = "/// foo\nfn bar() {}";
+
+ let mut host = AnalysisHost::default();
+ let change_fixture = ChangeFixture::parse(s);
+ host.raw_database_mut().apply_change(change_fixture.change);
+
+ let analysis = host.analysis();
+ let si = StaticIndex::compute(&analysis);
+
+ let file = si.files.first().unwrap();
+ let (_, token_id) = file.tokens.first().unwrap();
+ let token = si.tokens.get(*token_id).unwrap();
+
+ assert_eq!(token.documentation.as_ref().map(|d| d.as_str()), Some("foo"));
+ }
}