1use std::collections::HashMap;
16
17use hermes_parser::ast::node::{Node, NodeKind};
20use hermes_parser::ast::visitor::Visitor;
21use hermes_parser::{parse, ParseFlags};
22
23struct Histogram {
25 counts: HashMap<NodeKind, usize>,
26}
27
28impl<'gc> Visitor<'gc> for Histogram {
29 fn visit_node(&mut self, node: &'gc Node<'gc>) {
30 *self.counts.entry(node.kind()).or_default() += 1;
31 node.visit_children(self);
34 }
35}
36
37const SOURCE: &str = r#"
38class Counter {
39 #n = 0;
40 increment(by = 1) {
41 this.#n += by;
42 return this.#n;
43 }
44}
45
46const c = new Counter();
47for (const step of [1, 2, 3]) {
48 console.log(`${step} -> ${c.increment(step)}`);
49}
50"#;
51
52fn main() {
53 let flags = ParseFlags::default();
54 let mut parsed = parse(SOURCE, flags).expect("snippet must parse");
55
56 let counts = parsed.with_program(|_gc, program| {
59 let mut hist = Histogram {
60 counts: HashMap::new(),
61 };
62 hist.visit_node(program);
63 hist.counts
64 });
65
66 let mut rows: Vec<(NodeKind, usize)> = counts.into_iter().collect();
67 rows.sort_by(|a, b| {
69 b.1.cmp(&a.1)
70 .then_with(|| format!("{:?}", a.0).cmp(&format!("{:?}", b.0)))
71 });
72
73 let total: usize = rows.iter().map(|(_, n)| n).sum();
74 println!("{total} nodes, {} distinct kinds", rows.len());
75 for (kind, n) in rows {
76 println!("{:<24} {:>3} {}", format!("{kind:?}"), n, "#".repeat(n));
77 }
78}