Keep doc attribute order

This commit is contained in:
Lukas Wirth 2020-12-07 20:38:28 +01:00
parent efe86a42dc
commit b064f6da9e
3 changed files with 61 additions and 55 deletions

View file

@ -18,12 +18,33 @@ impl ast::Comment {
}
pub fn prefix(&self) -> &'static str {
let &(prefix, _kind) = CommentKind::BY_PREFIX
.iter()
.find(|&(prefix, kind)| self.kind() == *kind && self.text().starts_with(prefix))
.unwrap();
let &(prefix, _kind) = CommentKind::with_prefix_from_text(self.text());
prefix
}
pub fn kind_and_prefix(&self) -> &(&'static str, CommentKind) {
CommentKind::with_prefix_from_text(self.text())
}
/// Returns the textual content of a doc comment block as a single string.
/// That is, strips leading `///` (+ optional 1 character of whitespace),
/// trailing `*/`, trailing whitespace and then joins the lines.
pub fn doc_comment(&self) -> Option<&str> {
match self.kind_and_prefix() {
(prefix, CommentKind { shape, doc: Some(_) }) => {
let text = &self.text().as_str()[prefix.len()..];
let ws = text.chars().next().filter(|c| c.is_whitespace());
let text = ws.map_or(text, |ws| &text[ws.len_utf8()..]);
match shape {
CommentShape::Block if text.ends_with("*/") => {
Some(&text[..text.len() - "*/".len()])
}
_ => Some(text),
}
}
_ => None,
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@ -67,12 +88,13 @@ impl CommentKind {
];
pub(crate) fn from_text(text: &str) -> CommentKind {
let &(_prefix, kind) = CommentKind::BY_PREFIX
.iter()
.find(|&(prefix, _kind)| text.starts_with(prefix))
.unwrap();
let &(_prefix, kind) = Self::with_prefix_from_text(text);
kind
}
fn with_prefix_from_text(text: &str) -> &(&'static str, CommentKind) {
CommentKind::BY_PREFIX.iter().find(|&(prefix, _kind)| text.starts_with(prefix)).unwrap()
}
}
impl ast::Whitespace {

View file

@ -91,40 +91,12 @@ impl CommentIter {
/// That is, strips leading `///` (+ optional 1 character of whitespace),
/// trailing `*/`, trailing whitespace and then joins the lines.
pub fn doc_comment_text(self) -> Option<String> {
let mut has_comments = false;
let docs = self
.filter(|comment| comment.kind().doc.is_some())
.map(|comment| {
has_comments = true;
let prefix_len = comment.prefix().len();
let line: &str = comment.text().as_str();
// Determine if the prefix or prefix + 1 char is stripped
let pos =
if let Some(ws) = line.chars().nth(prefix_len).filter(|c| c.is_whitespace()) {
prefix_len + ws.len_utf8()
} else {
prefix_len
};
let end = if comment.kind().shape.is_block() && line.ends_with("*/") {
line.len() - 2
} else {
line.len()
};
// Note that we do not trim the end of the line here
// since whitespace can have special meaning at the end
// of a line in markdown.
line[pos..end].to_owned()
})
.join("\n");
if has_comments {
Some(docs)
} else {
let docs =
self.filter_map(|comment| comment.doc_comment().map(ToOwned::to_owned)).join("\n");
if docs.is_empty() {
None
} else {
Some(docs)
}
}
}