use std::collections::HashMap;
use hermes_parser::ast::node::{Node, NodeKind};
use hermes_parser::ast::visitor::Visitor;
use hermes_parser::{parse, ParseFlags};
struct Histogram {
counts: HashMap<NodeKind, usize>,
}
impl<'gc> Visitor<'gc> for Histogram {
fn visit_node(&mut self, node: &'gc Node<'gc>) {
*self.counts.entry(node.kind()).or_default() += 1;
node.visit_children(self);
}
}
const SOURCE: &str = r#"
class Counter {
#n = 0;
increment(by = 1) {
this.#n += by;
return this.#n;
}
}
const c = new Counter();
for (const step of [1, 2, 3]) {
console.log(`${step} -> ${c.increment(step)}`);
}
"#;
fn main() {
let flags = ParseFlags::default();
let mut parsed = parse(SOURCE, flags).expect("snippet must parse");
let counts = parsed.with_program(|_gc, program| {
let mut hist = Histogram {
counts: HashMap::new(),
};
hist.visit_node(program);
hist.counts
});
let mut rows: Vec<(NodeKind, usize)> = counts.into_iter().collect();
rows.sort_by(|a, b| {
b.1.cmp(&a.1)
.then_with(|| format!("{:?}", a.0).cmp(&format!("{:?}", b.0)))
});
let total: usize = rows.iter().map(|(_, n)| n).sum();
println!("{total} nodes, {} distinct kinds", rows.len());
for (kind, n) in rows {
println!("{:<24} {:>3} {}", format!("{kind:?}"), n, "#".repeat(n));
}
}