Skip to content

Commit 6eb0d59

Browse files
author
Loi Nguyen
committed
fix(filter): preserve code around block comments
1 parent f9d8c77 commit 6eb0d59

1 file changed

Lines changed: 82 additions & 17 deletions

File tree

src/core/filter.rs

Lines changed: 82 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -160,42 +160,83 @@ lazy_static! {
160160
static ref TRAILING_WHITESPACE: Regex = Regex::new(r"[ \t]+$").unwrap();
161161
}
162162

163+
fn strip_block_comments(
164+
line: &str,
165+
start: &str,
166+
end: &str,
167+
in_block_comment: &mut bool,
168+
) -> Option<String> {
169+
let mut remaining = line;
170+
let mut output = String::with_capacity(line.len());
171+
let mut removed_comment = *in_block_comment;
172+
173+
loop {
174+
if *in_block_comment {
175+
let Some(end_index) = remaining.find(end) else {
176+
break;
177+
};
178+
remaining = &remaining[end_index + end.len()..];
179+
*in_block_comment = false;
180+
continue;
181+
}
182+
183+
let Some(start_index) = remaining.find(start) else {
184+
output.push_str(remaining);
185+
break;
186+
};
187+
188+
removed_comment = true;
189+
output.push_str(&remaining[..start_index]);
190+
remaining = &remaining[start_index + start.len()..];
191+
*in_block_comment = true;
192+
}
193+
194+
let output = TRAILING_WHITESPACE.replace(&output, "").into_owned();
195+
if removed_comment && output.trim().is_empty() {
196+
None
197+
} else {
198+
Some(output)
199+
}
200+
}
201+
163202
impl FilterStrategy for MinimalFilter {
164203
fn filter(&self, content: &str, lang: &Language) -> String {
165204
let patterns = lang.comment_patterns();
166205
let mut result = String::with_capacity(content.len());
167206
let mut in_block_comment = false;
168207
let mut in_docstring = false;
169208

170-
for line in content.lines() {
171-
let trimmed = line.trim();
209+
for original_line in content.lines() {
210+
let mut line = original_line.to_string();
211+
let initial_trimmed = line.trim();
172212

173213
// Handle block comments
174214
if let (Some(start), Some(end)) = (patterns.block_start, patterns.block_end) {
175-
if !in_docstring
176-
&& trimmed.contains(start)
177-
&& !trimmed.starts_with(patterns.doc_block_start.unwrap_or("###"))
178-
{
179-
in_block_comment = true;
180-
}
181-
if in_block_comment {
182-
if trimmed.contains(end) {
183-
in_block_comment = false;
184-
}
185-
continue;
215+
let is_doc_block = patterns
216+
.doc_block_start
217+
.is_some_and(|doc| initial_trimmed.starts_with(doc));
218+
if !in_docstring && !is_doc_block {
219+
let Some(stripped) =
220+
strip_block_comments(&line, start, end, &mut in_block_comment)
221+
else {
222+
continue;
223+
};
224+
line = stripped;
186225
}
187226
}
188227

228+
let trimmed = line.trim();
229+
189230
// Handle Python docstrings (keep them in minimal mode)
190231
if *lang == Language::Python && trimmed.starts_with("\"\"\"") {
191232
in_docstring = !in_docstring;
192-
result.push_str(line);
233+
result.push_str(&line);
193234
result.push('\n');
194235
continue;
195236
}
196237

197238
if in_docstring {
198-
result.push_str(line);
239+
result.push_str(&line);
199240
result.push('\n');
200241
continue;
201242
}
@@ -206,7 +247,7 @@ impl FilterStrategy for MinimalFilter {
206247
// Keep doc comments
207248
if let Some(doc) = patterns.doc_line {
208249
if trimmed.starts_with(doc) {
209-
result.push_str(line);
250+
result.push_str(&line);
210251
result.push('\n');
211252
}
212253
}
@@ -220,7 +261,7 @@ impl FilterStrategy for MinimalFilter {
220261
continue;
221262
}
222263

223-
result.push_str(line);
264+
result.push_str(&line);
224265
result.push('\n');
225266
}
226267

@@ -470,6 +511,30 @@ fn main() {
470511
assert!(result.contains("fn main()"));
471512
}
472513

514+
#[test]
515+
fn test_minimal_filter_preserves_code_around_inline_block_comments() {
516+
let code = "int x = 5; /* inline comment */\n/* prefix */ int y = 10;\nint z = 15; /* middle */ z++;\n";
517+
let result = MinimalFilter.filter(code, &Language::C);
518+
519+
assert_eq!(result, "int x = 5;\n int y = 10;\nint z = 15; z++;");
520+
}
521+
522+
#[test]
523+
fn test_minimal_filter_preserves_code_after_multiline_comment() {
524+
let code = "int x = 1; /* multi-line\n comment */ int y = 2;\nint z = 3;\n";
525+
let result = MinimalFilter.filter(code, &Language::C);
526+
527+
assert_eq!(result, "int x = 1;\n int y = 2;\nint z = 3;");
528+
}
529+
530+
#[test]
531+
fn test_minimal_filter_keeps_rust_doc_blocks() {
532+
let code = "/** Important docs. */\nfn documented() {}\n";
533+
let result = MinimalFilter.filter(code, &Language::Rust);
534+
535+
assert_eq!(result, code.trim());
536+
}
537+
473538
// --- truncation accuracy ---
474539

475540
#[test]

0 commit comments

Comments
 (0)