Skip to content

Commit cd7d601

Browse files
author
Cameron McHenry
committed
feat(semantic): add methods to check if AST contains any/all node types
1 parent 74e03f9 commit cd7d601

File tree

1 file changed

+34
-1
lines changed

1 file changed

+34
-1
lines changed

crates/oxc_semantic/src/node.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::iter::FusedIterator;
22

33
use fixedbitset::FixedBitSet;
44
use oxc_allocator::{Address, GetAddress};
5-
use oxc_ast::{AstKind, ast::Program, ast_kind::AST_TYPE_MAX};
5+
use oxc_ast::{AstKind, AstType, ast::Program, ast_kind::AST_TYPE_MAX};
66
use oxc_cfg::BlockNodeId;
77
use oxc_index::{IndexSlice, IndexVec};
88
use oxc_span::{GetSpan, Span};
@@ -269,6 +269,39 @@ impl<'a> AstNodes<'a> {
269269
self.nodes.reserve(additional);
270270
self.parent_ids.reserve(additional);
271271
}
272+
273+
/// Checks if the AST contains any nodes of the given types.
274+
///
275+
/// Example:
276+
/// - `.contains_any(&[AstType::ForStatement])` returns `true` if there is a `for` loop anywhere in the AST.
277+
/// - `.contains_any(&[AstType::ImportDeclaration, AstType::ExportDeclaration])` returns `true` if there are any imports OR exports in the AST.
278+
pub fn contains_any(&self, types: &[AstType]) -> bool {
279+
// SAFETY: We already check that every `AstType` is within the bounds when inserting, so it should
280+
// be safe to access the bitset without bounds checking.
281+
types.iter().any(|ty| unsafe { self.node_kinds_set.contains_unchecked(*ty as usize) })
282+
}
283+
284+
/// Checks if the AST contains all of the given types.
285+
///
286+
/// Example:
287+
/// - `.contains_all(&[AstType::ForStatement])` returns `true` if there is a `for` loop anywhere in the AST.
288+
/// - `.contains_all(&[AstType::ImportDeclaration, AstType::ExportDeclaration])` returns `true` only if there is at least one import AND one export in the AST.
289+
pub fn contains_all(&self, types: &[AstType]) -> bool {
290+
// SAFETY: We already check that every `AstType` is within the bounds when inserting, so it should
291+
// be safe to access the bitset without bounds checking.
292+
types.iter().all(|ty| unsafe { self.node_kinds_set.contains_unchecked(*ty as usize) })
293+
}
294+
295+
/// Checks if the AST contains a node of the given type.
296+
///
297+
/// Example:
298+
/// - `.contains(AstType::ForStatement)` returns `true` if there is a `for` loop anywhere in the AST.
299+
/// - `.contains(AstType::ImportDeclaration)` returns `true` if there is an import in the AST.
300+
pub fn contains(&self, ty: AstType) -> bool {
301+
// SAFETY: We already check that every `AstType` is within the bounds when inserting, so it should
302+
// be safe to access the bitset without bounds checking.
303+
unsafe { self.node_kinds_set.contains_unchecked(ty as usize) }
304+
}
272305
}
273306

274307
impl<'a, 'n> IntoIterator for &'n AstNodes<'a> {

0 commit comments

Comments
 (0)