getPrecedingDocstring — collect the comment run immediately preceding the node (climbing out of declaration wrappers first), cleaned and joined. Returns None when there is no preceding comment (a PRESENT-but-empty docstring after cleaning still returns Some(""), matching the TS helper).
(node: Node, src: &str)
| 131 | /// Returns None when there is no preceding comment (a PRESENT-but-empty |
| 132 | /// docstring after cleaning still returns Some(""), matching the TS helper). |
| 133 | pub fn preceding_docstring(node: Node, src: &str) -> Option<String> { |
| 134 | let mut anchor = node; |
| 135 | while let Some(parent) = anchor.parent() { |
| 136 | if is_wrapper(parent.kind()) { |
| 137 | anchor = parent; |
| 138 | } else { |
| 139 | break; |
| 140 | } |
| 141 | } |
| 142 | |
| 143 | let mut comments: Vec<&str> = Vec::new(); |
| 144 | let mut sibling = anchor.prev_named_sibling(); |
| 145 | while let Some(s) = sibling { |
| 146 | if is_comment(s.kind()) { |
| 147 | comments.push(&src[s.byte_range()]); |
| 148 | sibling = s.prev_named_sibling(); |
| 149 | } else { |
| 150 | break; |
| 151 | } |
| 152 | } |
| 153 | if comments.is_empty() { |
| 154 | return None; |
| 155 | } |
| 156 | comments.reverse(); // collected nearest-first; TS unshifts to keep source order |
| 157 | Some( |
| 158 | comments |
| 159 | .iter() |
| 160 | .map(|c| clean_comment_markers(c)) |
| 161 | .collect::<Vec<_>>() |
| 162 | .join("\n") |
| 163 | .trim() |
| 164 | .to_string(), |
| 165 | ) |
| 166 | } |
| 167 | |
| 168 | #[cfg(test)] |
| 169 | mod tests { |
no test coverage detected