Skip to content

Commit a4f5a3a

Browse files
committed
feat(ast_tools): add Schema::structs_and_enums method (#13949)
Add a `structs_and_enums` method to `Schema` which returns an iterator over all struct and enum definitions, skipping primitives, boxes, vecs, etc. This will be useful in many places in `oxc_ast_tools`.
1 parent 43b74af commit a4f5a3a

File tree

3 files changed

+48
-1
lines changed

3 files changed

+48
-1
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.

tasks/ast_tools/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ test = true
1414
doctest = false
1515

1616
[dependencies]
17+
oxc_data_structures = { workspace = true, features = ["slice_iter"] }
18+
1719
bitflags = { workspace = true }
1820
bpaf = { workspace = true, features = ["autocomplete", "bright-color", "derive"] }
1921
convert_case = { workspace = true }

tasks/ast_tools/src/schema/mod.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
use oxc_index::{IndexVec, define_index_type};
1+
use std::{iter::FusedIterator, slice};
2+
23
use rustc_hash::FxHashMap;
34
// Have to import this even though don't use it, due to a bug in `define_index_type!` macro
45
#[expect(unused_imports)]
56
use serde::Serialize;
67

8+
use oxc_data_structures::slice_iter::SliceIter;
9+
use oxc_index::{IndexVec, define_index_type};
10+
711
mod defs;
812
mod derives;
913
mod file;
@@ -87,6 +91,12 @@ impl Schema {
8791
let meta_id = self.meta_names[name];
8892
&self.metas[meta_id]
8993
}
94+
95+
/// Get iterator over all structs and enums.
96+
#[expect(dead_code)]
97+
pub fn structs_and_enums(&self) -> StructsAndEnums<'_> {
98+
StructsAndEnums::new(self)
99+
}
90100
}
91101

92102
/// Methods for getting a specific type def (e.g. [`StructDef`]) for a [`TypeId`].
@@ -222,3 +232,37 @@ impl Schema {
222232
self.types[type_id].as_pointer_mut().unwrap()
223233
}
224234
}
235+
236+
/// Iterator over structs and enums.
237+
pub struct StructsAndEnums<'s> {
238+
iter: slice::Iter<'s, TypeDef>,
239+
}
240+
241+
impl<'s> StructsAndEnums<'s> {
242+
fn new(schema: &'s Schema) -> Self {
243+
Self { iter: schema.types.iter() }
244+
}
245+
}
246+
247+
impl<'s> Iterator for StructsAndEnums<'s> {
248+
type Item = StructOrEnum<'s>;
249+
250+
fn next(&mut self) -> Option<StructOrEnum<'s>> {
251+
if let Some(type_def) = self.iter.next() {
252+
match type_def {
253+
TypeDef::Struct(struct_def) => Some(StructOrEnum::Struct(struct_def)),
254+
TypeDef::Enum(enum_def) => Some(StructOrEnum::Enum(enum_def)),
255+
_ => {
256+
// Structs and enums are always first in `Schema::types`,
257+
// so if we encounter a different type, iteration is done.
258+
self.iter.advance_to_end();
259+
None
260+
}
261+
}
262+
} else {
263+
None
264+
}
265+
}
266+
}
267+
268+
impl FusedIterator for StructsAndEnums<'_> {}

0 commit comments

Comments
 (0)