1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//! Shared docstring extraction helpers.
//!
//! Free functions for extracting doc comments from AST nodes,
//! used by `Language::extract_docstring` implementations.
use tree_sitter::Node;
/// Extract a docstring from preceding comment nodes that use a given line prefix.
///
/// Walks backwards through siblings, collecting `comment` nodes whose text
/// starts with `prefix`. Stops at the first non-matching sibling.
///
/// # Example
///
/// ```ignore
/// // Lua: "---", R: "#'"
/// extract_preceding_prefix_comments(node, content, "---")
/// ```
pub(crate) fn extract_preceding_prefix_comments(
node: &Node,
content: &str,
prefix: &str,
) -> Option<String> {
let mut doc_lines: Vec<String> = Vec::new();
let mut prev = node.prev_sibling();
while let Some(sibling) = prev {
if sibling.kind() == "comment" {
let text = &content[sibling.byte_range()];
if let Some(line) = text.strip_prefix(prefix) {
let line = line.strip_prefix(' ').unwrap_or(line);
doc_lines.push(line.to_string());
} else {
break;
}
} else {
break;
}
prev = sibling.prev_sibling();
}
if doc_lines.is_empty() {
return None;
}
doc_lines.reverse();
let joined = doc_lines.join("\n").trim().to_string();
if joined.is_empty() {
None
} else {
Some(joined)
}
}