Skip to content

Commit 7f7b9ae

Browse files
committed
feat(ast): add is_inside_comment method
1 parent 90add74 commit 7f7b9ae

File tree

2 files changed

+49
-1
lines changed

2 files changed

+49
-1
lines changed

crates/oxc_ast/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub use crate::{
7878
ast_builder_impl::{AstBuilder, NONE},
7979
ast_kind::{AstKind, AstType},
8080
ast_kind_impl::{MemberExpressionKind, ModuleDeclarationKind},
81-
trivia::{CommentsRange, comments_range, has_comments_between},
81+
trivia::{CommentsRange, comments_range, has_comments_between, is_inside_comment},
8282
};
8383

8484
// After experimenting with two types of boxed enum variants:

crates/oxc_ast/src/trivia.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! including efficient range-based queries and iteration over comment collections.
55
66
use std::{
7+
cmp::Ordering,
78
iter::FusedIterator,
89
ops::{Bound, RangeBounds},
910
};
@@ -57,6 +58,39 @@ pub fn has_comments_between(comments: &[Comment], span: Span) -> bool {
5758
comments_range(comments, span.start..span.end).count() > 0
5859
}
5960

61+
/// Check if a position falls within any comment
62+
///
63+
/// Returns `true` if the specified position is inside any comment's span,
64+
/// including the start and end positions.
65+
///
66+
/// Uses binary search for efficient lookup in O(log n) time.
67+
///
68+
/// # Arguments
69+
///
70+
/// * `comments` - A slice of comments sorted by starting position
71+
/// * `pos` - The position to check
72+
///
73+
/// # Examples
74+
///
75+
/// ```ignore
76+
/// // Comment spans from position 10 to 20
77+
/// assert!(is_inside_comment(&comments, 15)); // Inside comment
78+
/// assert!(!is_inside_comment(&comments, 25)); // Outside comment
79+
/// ```
80+
pub fn is_inside_comment(comments: &[Comment], pos: u32) -> bool {
81+
comments
82+
.binary_search_by(|c| {
83+
if pos < c.span.start {
84+
Ordering::Greater
85+
} else if pos > c.span.end {
86+
Ordering::Less
87+
} else {
88+
Ordering::Equal
89+
}
90+
})
91+
.is_ok()
92+
}
93+
6094
/// Double-ended iterator over a range of comments, by starting position
6195
///
6296
/// This iterator efficiently filters comments based on their starting positions,
@@ -162,4 +196,18 @@ mod test {
162196
assert_eq!(comments_range(&comments, ..18).count(), full_len.saturating_sub(1));
163197
assert_eq!(comments_range(&comments, ..=18).count(), full_len);
164198
}
199+
200+
#[test]
201+
fn test_is_inside_comment() {
202+
let comments = vec![
203+
Comment::new(0, 4, CommentKind::Line),
204+
Comment::new(10, 20, CommentKind::Block),
205+
]
206+
.into_boxed_slice();
207+
208+
assert!(is_inside_comment(&comments, 2));
209+
assert!(!is_inside_comment(&comments, 5));
210+
assert!(is_inside_comment(&comments, 15));
211+
assert!(!is_inside_comment(&comments, 21));
212+
}
165213
}

0 commit comments

Comments
 (0)