diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_def/src/docs.rs | 7 | ||||
-rw-r--r-- | crates/ra_ide/src/hover.rs | 60 |
2 files changed, 14 insertions, 53 deletions
diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs index ab43cd3d3..2630b3d89 100644 --- a/crates/ra_hir_def/src/docs.rs +++ b/crates/ra_hir_def/src/docs.rs | |||
@@ -29,6 +29,13 @@ impl Documentation { | |||
29 | Documentation(s.into()) | 29 | Documentation(s.into()) |
30 | } | 30 | } |
31 | 31 | ||
32 | pub fn from_ast<N>(node: &N) -> Option<Documentation> | ||
33 | where | ||
34 | N: ast::DocCommentsOwner + ast::AttrsOwner, | ||
35 | { | ||
36 | docs_from_ast(node) | ||
37 | } | ||
38 | |||
32 | pub fn as_str(&self) -> &str { | 39 | pub fn as_str(&self) -> &str { |
33 | &*self.0 | 40 | &*self.0 |
34 | } | 41 | } |
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs index 731fc3673..9636cd0d6 100644 --- a/crates/ra_ide/src/hover.rs +++ b/crates/ra_ide/src/hover.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | use std::iter::once; | 1 | use std::iter::once; |
2 | 2 | ||
3 | use hir::{ | 3 | use hir::{ |
4 | Adt, AsAssocItem, AssocItemContainer, FieldSource, HasSource, HirDisplay, ModuleDef, | 4 | Adt, AsAssocItem, AssocItemContainer, Documentation, FieldSource, HasSource, HirDisplay, |
5 | ModuleSource, Semantics, | 5 | ModuleDef, ModuleSource, Semantics, |
6 | }; | 6 | }; |
7 | use itertools::Itertools; | 7 | use itertools::Itertools; |
8 | use ra_db::SourceDatabase; | 8 | use ra_db::SourceDatabase; |
@@ -10,12 +10,7 @@ use ra_ide_db::{ | |||
10 | defs::{classify_name, classify_name_ref, Definition}, | 10 | defs::{classify_name, classify_name_ref, Definition}, |
11 | RootDatabase, | 11 | RootDatabase, |
12 | }; | 12 | }; |
13 | use ra_syntax::{ | 13 | use ra_syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset}; |
14 | ast::{self, DocCommentsOwner}, | ||
15 | match_ast, AstNode, | ||
16 | SyntaxKind::*, | ||
17 | SyntaxToken, TokenAtOffset, | ||
18 | }; | ||
19 | 14 | ||
20 | use crate::{ | 15 | use crate::{ |
21 | display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel}, | 16 | display::{macro_label, rust_code_markup, rust_code_markup_with_doc, ShortLabel}, |
@@ -169,18 +164,14 @@ fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<Strin | |||
169 | return match def { | 164 | return match def { |
170 | Definition::Macro(it) => { | 165 | Definition::Macro(it) => { |
171 | let src = it.source(db); | 166 | let src = it.source(db); |
172 | let doc_comment_text = src.value.doc_comment_text(); | 167 | let docs = Documentation::from_ast(&src.value).map(Into::into); |
173 | let doc_attr_text = expand_doc_attrs(&src.value); | ||
174 | let docs = merge_doc_comments_and_attrs(doc_comment_text, doc_attr_text); | ||
175 | hover_text(docs, Some(macro_label(&src.value)), mod_path) | 168 | hover_text(docs, Some(macro_label(&src.value)), mod_path) |
176 | } | 169 | } |
177 | Definition::Field(it) => { | 170 | Definition::Field(it) => { |
178 | let src = it.source(db); | 171 | let src = it.source(db); |
179 | match src.value { | 172 | match src.value { |
180 | FieldSource::Named(it) => { | 173 | FieldSource::Named(it) => { |
181 | let doc_comment_text = it.doc_comment_text(); | 174 | let docs = Documentation::from_ast(&it).map(Into::into); |
182 | let doc_attr_text = expand_doc_attrs(&it); | ||
183 | let docs = merge_doc_comments_and_attrs(doc_comment_text, doc_attr_text); | ||
184 | hover_text(docs, it.short_label(), mod_path) | 175 | hover_text(docs, it.short_label(), mod_path) |
185 | } | 176 | } |
186 | _ => None, | 177 | _ => None, |
@@ -189,9 +180,7 @@ fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<Strin | |||
189 | Definition::ModuleDef(it) => match it { | 180 | Definition::ModuleDef(it) => match it { |
190 | ModuleDef::Module(it) => match it.definition_source(db).value { | 181 | ModuleDef::Module(it) => match it.definition_source(db).value { |
191 | ModuleSource::Module(it) => { | 182 | ModuleSource::Module(it) => { |
192 | let doc_comment_text = it.doc_comment_text(); | 183 | let docs = Documentation::from_ast(&it).map(Into::into); |
193 | let doc_attr_text = expand_doc_attrs(&it); | ||
194 | let docs = merge_doc_comments_and_attrs(doc_comment_text, doc_attr_text); | ||
195 | hover_text(docs, it.short_label(), mod_path) | 184 | hover_text(docs, it.short_label(), mod_path) |
196 | } | 185 | } |
197 | _ => None, | 186 | _ => None, |
@@ -220,46 +209,11 @@ fn hover_text_from_name_kind(db: &RootDatabase, def: Definition) -> Option<Strin | |||
220 | A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel + ast::AttrsOwner, | 209 | A: ast::DocCommentsOwner + ast::NameOwner + ShortLabel + ast::AttrsOwner, |
221 | { | 210 | { |
222 | let src = def.source(db); | 211 | let src = def.source(db); |
223 | let doc_comment_text = src.value.doc_comment_text(); | 212 | let docs = Documentation::from_ast(&src.value).map(Into::into); |
224 | let doc_attr_text = expand_doc_attrs(&src.value); | ||
225 | let docs = merge_doc_comments_and_attrs(doc_comment_text, doc_attr_text); | ||
226 | hover_text(docs, src.value.short_label(), mod_path) | 213 | hover_text(docs, src.value.short_label(), mod_path) |
227 | } | 214 | } |
228 | } | 215 | } |
229 | 216 | ||
230 | fn merge_doc_comments_and_attrs( | ||
231 | doc_comment_text: Option<String>, | ||
232 | doc_attr_text: Option<String>, | ||
233 | ) -> Option<String> { | ||
234 | match (doc_comment_text, doc_attr_text) { | ||
235 | (Some(mut comment_text), Some(attr_text)) => { | ||
236 | comment_text.push_str("\n\n"); | ||
237 | comment_text.push_str(&attr_text); | ||
238 | Some(comment_text) | ||
239 | } | ||
240 | (Some(comment_text), None) => Some(comment_text), | ||
241 | (None, Some(attr_text)) => Some(attr_text), | ||
242 | (None, None) => None, | ||
243 | } | ||
244 | } | ||
245 | |||
246 | fn expand_doc_attrs(owner: &dyn ast::AttrsOwner) -> Option<String> { | ||
247 | let mut docs = String::new(); | ||
248 | for attr in owner.attrs() { | ||
249 | if let Some(("doc", value)) = | ||
250 | attr.as_simple_key_value().as_ref().map(|(k, v)| (k.as_str(), v.as_str())) | ||
251 | { | ||
252 | docs.push_str(value); | ||
253 | docs.push_str("\n\n"); | ||
254 | } | ||
255 | } | ||
256 | if docs.is_empty() { | ||
257 | None | ||
258 | } else { | ||
259 | Some(docs.trim_end_matches("\n\n").to_owned()) | ||
260 | } | ||
261 | } | ||
262 | |||
263 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | 217 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { |
264 | return tokens.max_by_key(priority); | 218 | return tokens.max_by_key(priority); |
265 | fn priority(n: &SyntaxToken) -> usize { | 219 | fn priority(n: &SyntaxToken) -> usize { |