Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/sourcegen/src/lib.rs')
| -rw-r--r-- | crates/sourcegen/src/lib.rs | 93 |
1 files changed, 48 insertions, 45 deletions
diff --git a/crates/sourcegen/src/lib.rs b/crates/sourcegen/src/lib.rs index 2d28066342..6a332bce85 100644 --- a/crates/sourcegen/src/lib.rs +++ b/crates/sourcegen/src/lib.rs @@ -43,10 +43,12 @@ pub fn list_files(dir: &Path) -> Vec<PathBuf> { res } +#[derive(Clone)] pub struct CommentBlock { pub id: String, pub line: usize, pub contents: Vec<String>, + is_doc: bool, } impl CommentBlock { @@ -54,59 +56,60 @@ impl CommentBlock { assert!(tag.starts_with(char::is_uppercase)); let tag = format!("{}:", tag); - let mut res = Vec::new(); - for (line, mut block) in do_extract_comment_blocks(text, true) { - let first = block.remove(0); - if let Some(id) = first.strip_prefix(&tag) { - let id = id.trim().to_string(); - let block = CommentBlock { id, line, contents: block }; - res.push(block); - } - } - res + // Would be nice if we had `.retain_mut` here! + CommentBlock::extract_untagged(text) + .into_iter() + .filter_map(|mut block| { + let first = block.contents.remove(0); + first.strip_prefix(&tag).map(|id| { + if block.is_doc { + panic!( + "Use plain (non-doc) comments with tags like {}:\n {}", + tag, first + ) + } + + block.id = id.trim().to_string(); + block + }) + }) + .collect() } pub fn extract_untagged(text: &str) -> Vec<CommentBlock> { let mut res = Vec::new(); - for (line, block) in do_extract_comment_blocks(text, false) { - let id = String::new(); - let block = CommentBlock { id, line, contents: block }; - res.push(block); - } - res - } -} - -fn do_extract_comment_blocks( - text: &str, - allow_blocks_with_empty_lines: bool, -) -> Vec<(usize, Vec<String>)> { - let mut res = Vec::new(); - let prefix = "// "; - let lines = text.lines().map(str::trim_start); - - let mut block = (0, vec![]); - for (line_num, line) in lines.enumerate() { - if line == "//" && allow_blocks_with_empty_lines { - block.1.push(String::new()); - continue; - } - - let is_comment = line.starts_with(prefix); - if is_comment { - block.1.push(line[prefix.len()..].to_string()); - } else { - if !block.1.is_empty() { - res.push(mem::take(&mut block)); + let lines = text.lines().map(str::trim_start); + + let dummy_block = + CommentBlock { id: String::new(), line: 0, contents: Vec::new(), is_doc: false }; + let mut block = dummy_block.clone(); + for (line_num, line) in lines.enumerate() { + match line.strip_prefix("//") { + Some(mut contents) => { + if let Some('/' | '!') = contents.chars().next() { + contents = &contents[1..]; + block.is_doc = true; + } + if let Some(' ') = contents.chars().next() { + contents = &contents[1..]; + } + block.contents.push(contents.to_string()); + } + None => { + if !block.contents.is_empty() { + let block = mem::replace(&mut block, dummy_block.clone()); + res.push(block); + } + block.line = line_num + 2; + } } - block.0 = line_num + 2; } + if !block.contents.is_empty() { + res.push(block) + } + res } - if !block.1.is_empty() { - res.push(block) - } - res } #[derive(Debug)] |