Skip to content

Commit 891c8d1

Browse files
author
Cameron McHenry
committed
feat(semantic): add set of AstType that exist in AST
1 parent ea30a17 commit 891c8d1

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/oxc_semantic/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ oxc_index = { workspace = true }
3030
oxc_span = { workspace = true }
3131
oxc_syntax = { workspace = true }
3232

33+
fixedbitset = { workspace = true }
3334
itertools = { workspace = true }
3435
phf = { workspace = true, features = ["macros"] }
3536
rustc-hash = { workspace = true }

crates/oxc_semantic/src/node.rs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::iter::FusedIterator;
22

3+
use fixedbitset::FixedBitSet;
34
use oxc_allocator::{Address, GetAddress};
4-
use oxc_ast::{AstKind, ast::Program};
5+
use oxc_ast::{AstKind, ast::Program, ast_kind::AST_TYPE_MAX};
56
use oxc_cfg::BlockNodeId;
67
use oxc_index::{IndexSlice, IndexVec};
78
use oxc_span::{GetSpan, Span};
@@ -96,14 +97,29 @@ impl GetAddress for AstNode<'_> {
9697
}
9798

9899
/// Untyped AST nodes flattened into an vec
99-
#[derive(Debug, Default)]
100+
#[derive(Debug)]
100101
pub struct AstNodes<'a> {
101102
program: Option<&'a Program<'a>>,
102103
nodes: IndexVec<NodeId, AstNode<'a>>,
104+
/// Stores a set of bits of a fixed size, where each bit represents a single [`AstKind`]. If the bit is set (1),
105+
/// then the AST contains at least one node of that kind. If the bit is not set (0), then the AST does not contain
106+
/// any nodes of that kind.
107+
node_kinds_set: FixedBitSet,
103108
/// `node` -> `parent`
104109
parent_ids: IndexVec<NodeId, NodeId>,
105110
}
106111

112+
impl Default for AstNodes<'_> {
113+
fn default() -> Self {
114+
Self {
115+
program: None,
116+
nodes: IndexVec::new(),
117+
node_kinds_set: FixedBitSet::with_capacity(AST_TYPE_MAX as usize + 1),
118+
parent_ids: IndexVec::new(),
119+
}
120+
}
121+
}
122+
107123
impl<'a> AstNodes<'a> {
108124
/// Iterate over all [`AstNode`]s in this AST.
109125
pub fn iter(&self) -> impl Iterator<Item = &AstNode<'a>> + '_ {
@@ -210,6 +226,12 @@ impl<'a> AstNodes<'a> {
210226
let node_id = self.parent_ids.push(parent_node_id);
211227
let node = AstNode::new(kind, scope_id, cfg_id, flags, node_id);
212228
self.nodes.push(node);
229+
debug_assert!((kind.ty() as usize) < self.node_kinds_set.len());
230+
// SAFETY: `AstKind` maps exactly to `AstType`, and there should be exactly
231+
// enough bits to insert it into `node_kinds`, so we can skip a bounds check here.
232+
unsafe {
233+
self.node_kinds_set.insert_unchecked(kind.ty() as usize);
234+
}
213235
node_id
214236
}
215237

@@ -233,6 +255,12 @@ impl<'a> AstNodes<'a> {
233255
let node_id = self.parent_ids.push(NodeId::ROOT);
234256
let node = AstNode::new(kind, scope_id, cfg_id, flags, node_id);
235257
self.nodes.push(node);
258+
debug_assert!((kind.ty() as usize) < self.node_kinds_set.len());
259+
// SAFETY: `AstKind` maps exactly to `AstType`, and there should be exactly
260+
// enough bits to insert it into `node_kinds`, so we can skip a bounds check here.
261+
unsafe {
262+
self.node_kinds_set.insert_unchecked(kind.ty() as usize);
263+
}
236264
node_id
237265
}
238266

0 commit comments

Comments
 (0)