use hermes_ast::context::Context;
use hermes_parser::js::JSParserImpl;
use hermes_parser::lexer::{GrammarContext, JSLexer};
use hermes_support::manager::SourceErrorManager;
fn gen_source(n: usize) -> Vec<u8> {
let mut src = Vec::new();
for f in 0..n {
src.extend_from_slice(format!("function f{f}(a, b) {{\n").as_bytes());
for i in 0..20 {
src.extend_from_slice(format!(" var x{i} = a + b * {i};\n").as_bytes());
}
src.extend_from_slice(b" return a;\n}\n");
}
src
}
fn eager_nodes(src: &[u8]) -> usize {
let mut sm = SourceErrorManager::new();
let id = sm.add_buffer_bytes("t", src);
let mut ctx = Context::new();
let gc = ctx.lock();
let atoms = &gc.ctx().atom_table;
let lexer = JSLexer::new(id, &mut sm, atoms, GrammarContext::AllowRegExp);
let mut p = JSParserImpl::new(&gc, lexer);
assert!(p.parse().is_some());
gc.ctx().num_nodes()
}
fn preparse_nodes(src: &[u8]) -> (usize, usize) {
let mut sm = SourceErrorManager::new();
let id = sm.add_buffer_bytes("t", src);
let mut ctx = Context::new();
let gc = ctx.lock();
let atoms = &gc.ctx().atom_table;
let lexer = JSLexer::new(id, &mut sm, atoms, GrammarContext::AllowRegExp);
let p = JSParserImpl::pre_parse_buffer(&gc, lexer, false)
.expect("preparse failed");
let n = (gc.ctx().num_nodes(), gc.ctx().num_list_elements());
let mut p = p;
assert_eq!(p.take_pre_parsed().function_info.len(), 200);
n
}
#[test]
fn preparse_retains_no_ast() {
let one = gen_source(1);
let many = gen_source(200);
let e1 = eager_nodes(&one);
let e200 = eager_nodes(&many);
let (p200_nodes, p200_elems) = preparse_nodes(&many);
assert!(p200_nodes < e1, "retained nodes: {p200_nodes} (one-fn = {e1})");
assert!(p200_nodes * 20 < e200, "nodes {p200_nodes} vs eager {e200}");
assert!(p200_elems < e1, "retained list elements: {p200_elems}");
}