Skip to content

Commit 2187dbd

Browse files
committed
Generalize NamespaceEntries to generic Hierarchy builder
#382
1 parent 8e2faa4 commit 2187dbd

File tree

5 files changed

+63
-158
lines changed

5 files changed

+63
-158
lines changed

gen/src/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ pub(super) mod fs;
1010
mod ifndef;
1111
pub(super) mod include;
1212
mod namespace;
13-
mod nested;
1413
pub(super) mod out;
1514
mod write;
1615

gen/src/nested.rs

Lines changed: 0 additions & 153 deletions
This file was deleted.

gen/src/write.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::gen::block::Block;
2-
use crate::gen::nested::NamespaceEntries;
32
use crate::gen::out::OutFile;
43
use crate::gen::{builtin, include, Opt};
54
use crate::syntax::atom::Atom::{self, *};
5+
use crate::syntax::hierarchy::Hierarchy;
66
use crate::syntax::instantiate::ImplKey;
77
use crate::syntax::map::UnorderedMap as Map;
88
use crate::syntax::set::UnorderedSet;
@@ -39,12 +39,12 @@ fn write_forward_declarations(out: &mut OutFile, apis: &[Api]) {
3939
_ => false,
4040
};
4141

42-
let apis_by_namespace =
43-
NamespaceEntries::new(apis.iter().filter(needs_forward_declaration).collect());
42+
let forward_apis = apis.iter().filter(needs_forward_declaration).collect();
43+
let apis_by_namespace = Hierarchy::new(forward_apis, Api::namespace);
4444

4545
write(out, &apis_by_namespace, 0);
4646

47-
fn write(out: &mut OutFile, ns_entries: &NamespaceEntries, indent: usize) {
47+
fn write(out: &mut OutFile, ns_entries: &Hierarchy<Ident, Api>, indent: usize) {
4848
let apis = ns_entries.direct_content();
4949

5050
for api in apis {

syntax/hierarchy.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
use crate::syntax::map::UnorderedMap as Map;
2+
use std::hash::Hash;
3+
4+
pub struct Hierarchy<'a, K, T> {
5+
direct: Vec<&'a T>,
6+
nested: Vec<(&'a K, Hierarchy<'a, K, T>)>,
7+
}
8+
9+
impl<'a, K, T> Hierarchy<'a, K, T> {
10+
pub fn new<F, I>(items: Vec<&'a T>, keyfn: F) -> Self
11+
where
12+
K: Hash + Eq,
13+
F: Fn(&'a T) -> I,
14+
I: IntoIterator<Item = &'a K>,
15+
{
16+
sort_by_level(items, &keyfn, 0)
17+
}
18+
19+
pub fn direct_content(&self) -> &[&'a T] {
20+
&self.direct
21+
}
22+
23+
pub fn nested_content(&self) -> impl Iterator<Item = (&'a K, &Hierarchy<'a, K, T>)> {
24+
self.nested.iter().map(|(k, entries)| (*k, entries))
25+
}
26+
}
27+
28+
fn sort_by_level<'a, K, T, F, I>(items: Vec<&'a T>, keyfn: &F, depth: usize) -> Hierarchy<'a, K, T>
29+
where
30+
K: Hash + Eq,
31+
F: Fn(&'a T) -> I,
32+
I: IntoIterator<Item = &'a K>,
33+
{
34+
let mut direct = Vec::new();
35+
let mut nested_levels = Vec::new();
36+
let mut index_of_levels = Map::new();
37+
38+
for item in items {
39+
if let Some(elem) = keyfn(item).into_iter().nth(depth) {
40+
match index_of_levels.get(elem) {
41+
None => {
42+
index_of_levels.insert(elem, nested_levels.len());
43+
nested_levels.push((elem, vec![item]));
44+
}
45+
Some(&index) => nested_levels[index].1.push(item),
46+
}
47+
continue;
48+
}
49+
direct.push(item);
50+
}
51+
52+
let nested = nested_levels
53+
.into_iter()
54+
.map(|(k, items)| (k, sort_by_level(items, keyfn, depth + 1)))
55+
.collect();
56+
57+
Hierarchy { direct, nested }
58+
}

syntax/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod discriminant;
88
mod doc;
99
pub mod error;
1010
pub mod file;
11+
pub mod hierarchy;
1112
pub mod ident;
1213
mod impls;
1314
mod improper;

0 commit comments

Comments
 (0)