aboutsummaryrefslogtreecommitdiff
path: root/crates/syntax
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-12-08 13:23:12 +0000
committerGitHub <[email protected]>2020-12-08 13:23:12 +0000
commit2aa7f2ece517a5202421f7a4a7cdd99bd1862ac8 (patch)
treefcdf682d2175735262a7d733043bb510fd86526e /crates/syntax
parent4d4f11925f793c45560c45c088d4b3139c2c171c (diff)
parent3174e941dbb7d91bad011ba51a9b55736996b36c (diff)
Merge #6750
6750: Remove documentation query, move doc handling to attributes r=matklad a=Veykril Fixes #3182 Removes the documentation query in favor of `Attrs::docs`. Attrs already handlded doc comments partially but the alloc saving check was wrong so it only worked when other attributes existed as well. Unfortunately the `new` constructor has to do an intermediate allocation now because we need to keep the order of mixed doc attributes and doc comments. I've also partially adjusted the `hover` module to have its tests check the changes, it still has some `HasSource` trait usage due to the `ShortLabel` trait usage, as that is only implemented on the Ast parts and not the Hir, should this ideally be implemented for the Hir types as well?(would be a follow up PR of course) Co-authored-by: Lukas Wirth <[email protected]>
Diffstat (limited to 'crates/syntax')
-rw-r--r--crates/syntax/src/ast/token_ext.rs27
-rw-r--r--crates/syntax/src/ast/traits.rs38
2 files changed, 32 insertions, 33 deletions
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index fa40e64e8..a10b14778 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -24,6 +24,28 @@ impl ast::Comment {
24 .unwrap(); 24 .unwrap();
25 prefix 25 prefix
26 } 26 }
27
28 /// Returns the textual content of a doc comment block as a single string.
29 /// That is, strips leading `///` (+ optional 1 character of whitespace),
30 /// trailing `*/`, trailing whitespace and then joins the lines.
31 pub fn doc_comment(&self) -> Option<&str> {
32 let kind = self.kind();
33 match kind {
34 CommentKind { shape, doc: Some(_) } => {
35 let prefix = kind.prefix();
36 let text = &self.text().as_str()[prefix.len()..];
37 let ws = text.chars().next().filter(|c| c.is_whitespace());
38 let text = ws.map_or(text, |ws| &text[ws.len_utf8()..]);
39 match shape {
40 CommentShape::Block if text.ends_with("*/") => {
41 Some(&text[..text.len() - "*/".len()])
42 }
43 _ => Some(text),
44 }
45 }
46 _ => None,
47 }
48 }
27} 49}
28 50
29#[derive(Debug, PartialEq, Eq, Clone, Copy)] 51#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -73,6 +95,11 @@ impl CommentKind {
73 .unwrap(); 95 .unwrap();
74 kind 96 kind
75 } 97 }
98
99 fn prefix(&self) -> &'static str {
100 let &(prefix, _) = CommentKind::BY_PREFIX.iter().find(|(_, kind)| kind == self).unwrap();
101 prefix
102 }
76} 103}
77 104
78impl ast::Whitespace { 105impl ast::Whitespace {
diff --git a/crates/syntax/src/ast/traits.rs b/crates/syntax/src/ast/traits.rs
index 0bdc22d95..13a769d51 100644
--- a/crates/syntax/src/ast/traits.rs
+++ b/crates/syntax/src/ast/traits.rs
@@ -91,40 +91,12 @@ impl CommentIter {
91 /// That is, strips leading `///` (+ optional 1 character of whitespace), 91 /// That is, strips leading `///` (+ optional 1 character of whitespace),
92 /// trailing `*/`, trailing whitespace and then joins the lines. 92 /// trailing `*/`, trailing whitespace and then joins the lines.
93 pub fn doc_comment_text(self) -> Option<String> { 93 pub fn doc_comment_text(self) -> Option<String> {
94 let mut has_comments = false; 94 let docs =
95 let docs = self 95 self.filter_map(|comment| comment.doc_comment().map(ToOwned::to_owned)).join("\n");
96 .filter(|comment| comment.kind().doc.is_some()) 96 if docs.is_empty() {
97 .map(|comment| {
98 has_comments = true;
99 let prefix_len = comment.prefix().len();
100
101 let line: &str = comment.text().as_str();
102
103 // Determine if the prefix or prefix + 1 char is stripped
104 let pos =
105 if let Some(ws) = line.chars().nth(prefix_len).filter(|c| c.is_whitespace()) {
106 prefix_len + ws.len_utf8()
107 } else {
108 prefix_len
109 };
110
111 let end = if comment.kind().shape.is_block() && line.ends_with("*/") {
112 line.len() - 2
113 } else {
114 line.len()
115 };
116
117 // Note that we do not trim the end of the line here
118 // since whitespace can have special meaning at the end
119 // of a line in markdown.
120 line[pos..end].to_owned()
121 })
122 .join("\n");
123
124 if has_comments {
125 Some(docs)
126 } else {
127 None 97 None
98 } else {
99 Some(docs)
128 } 100 }
129 } 101 }
130} 102}