1#![expect(clippy::print_stdout)]
2use std::{env, path::Path};
15
16use oxc_allocator::Allocator;
17use oxc_ast::ast::{Class, Function, TSImportType};
18use oxc_ast_visit::{Visit, walk};
19use oxc_parser::Parser;
20use oxc_span::SourceType;
21use oxc_syntax::scope::ScopeFlags;
22
23fn main() -> std::io::Result<()> {
30 let name = env::args().nth(1).unwrap_or_else(|| "test.js".to_string());
31 let path = Path::new(&name);
32 let source_text = std::fs::read_to_string(path)?;
33 let allocator = Allocator::default();
34 let source_type = SourceType::from_path(path).unwrap();
35 let ret = Parser::new(&allocator, &source_text, source_type).parse();
36
37 for error in ret.diagnostics {
39 let error = error.with_source_code(source_text.clone());
40 println!("{error:?}");
41 }
42
43 let program = ret.program;
44
45 let mut ast_pass = CountASTNodes::default();
47 ast_pass.visit_program(&program);
48 println!("{ast_pass:?}");
49
50 Ok(())
51}
52
53#[derive(Debug, Default)]
55struct CountASTNodes {
56 functions: usize,
57 classes: usize,
58 ts_import_types: usize,
59}
60
61impl<'a> Visit<'a> for CountASTNodes {
62 fn visit_function(&mut self, func: &Function<'a>, flags: ScopeFlags) {
63 self.functions += 1;
64 walk::walk_function(self, func, flags);
65 }
66
67 fn visit_class(&mut self, class: &Class<'a>) {
68 self.classes += 1;
69 walk::walk_class(self, class);
70 }
71
72 fn visit_ts_import_type(&mut self, ty: &TSImportType<'a>) {
73 self.ts_import_types += 1;
74 walk::walk_ts_import_type(self, ty);
75 }
76}