use hermes_ast::context::{Context, GCLock, NodeRc};
use hermes_ast::node::{BlockStatement, FunctionDeclaration, Identifier, Node};
use hermes_ast::node_child::{NodeList, NodeMetadata};
use hermes_sema::dump_context::SemContextDumper;
use hermes_sema::keywords::Keywords;
use hermes_sema::sem_context::{
ConstructorKind, DeclKind, DeclSpecial, FuncIsArrow, SemContext,
};
fn r() -> hermes_support::location::SMRange {
let l = hermes_support::location::SMLoc {
source: hermes_support::location::SourceId::from_index(0),
offset: 0,
};
hermes_support::location::SMRange { start: l, end: l }
}
#[test]
fn prints_global_function_scope_decls_and_nested_strict_function() {
let mut ctx = Context::new();
let gc = GCLock::new(&mut ctx);
let mut sc = SemContext::new(Keywords::new(&gc));
let global_fn = sc.new_function(
FuncIsArrow::No,
ConstructorKind::None,
None,
None,
false,
Default::default(),
);
let global_scope = sc.new_scope(global_fn, None);
sc.new_decl_in_scope(
gc.atom_bytes("x"),
DeclKind::Let,
global_scope,
DeclSpecial::NotSpecial,
);
sc.new_decl_in_scope(
gc.atom_bytes("f"),
DeclKind::GlobalProperty,
global_scope,
DeclSpecial::NotSpecial,
);
let nested_fn = sc.new_function(
FuncIsArrow::No,
ConstructorKind::None,
Some(global_fn),
Some(global_scope),
true,
Default::default(),
);
let nested_scope = sc.new_scope(nested_fn, None);
let g_id = gc.alloc(Node::Identifier(Identifier::new(
NodeMetadata::new(r()),
gc.atom_bytes("g"),
None,
false,
)));
let g_decl_node = gc.alloc(Node::FunctionDeclaration(
FunctionDeclaration::new(
NodeMetadata::new(r()),
Some(g_id),
NodeList::empty(),
gc.alloc(Node::BlockStatement(BlockStatement::new(
NodeMetadata::new(r()),
NodeList::empty(),
false,
))),
None,
None,
None,
false,
false,
),
));
sc.scope_mut(nested_scope)
.hoisted_functions
.push(NodeRc::from_node(&gc, g_decl_node));
let mut dumper = SemContextDumper::new();
let mut out = Vec::new();
dumper.print_sem_context(&mut out, &gc, &sc, None);
let expected = "\
SemContext
Func loose mayReachImplicitReturn
Scope %s.1
Decl %d.1 'x' Let
Decl %d.2 'f' GlobalProperty
Func strict mayReachImplicitReturn
Scope %s.2
hoistedFunction g
";
assert_eq!(String::from_utf8(out).unwrap(), expected);
}