Skip to main content

rolldown_ecmascript/ecma_ast/
helpers.rs

1use oxc::{
2  ast::ast::Program,
3  semantic::{Scoping, Semantic, SemanticBuilder},
4};
5
6use crate::EcmaAst;
7
8/// Returns a [`SemanticBuilder`] pre-configured for any `Scoping` that will be
9/// passed to `Transformer::build_with_scoping`.
10///
11/// The TS transformer's enum lowering reads each member's constant value via
12/// `Scoping::get_enum_member_value`. That table is only populated when the
13/// builder has `enum_eval` enabled — without it, member aliases like
14/// `Default = Theme.Light` fall through to the buggy reverse-mapping form for
15/// string enums (`Foo[Foo["x"] = init] = "x"`), which corrupts the original
16/// member's reverse mapping. Callers may chain additional options (e.g.
17/// `with_check_syntax_error`, `with_stats`) on top.
18pub fn semantic_builder_for_transform<'a>() -> SemanticBuilder<'a> {
19  SemanticBuilder::new().with_enum_eval(true)
20}
21
22impl EcmaAst {
23  pub fn is_body_empty(&self) -> bool {
24    self.program().is_empty()
25  }
26
27  pub fn make_semantic<'ast>(program: &'ast Program<'ast>, with_cfg: bool) -> Semantic<'ast> {
28    SemanticBuilder::new().with_cfg(with_cfg).build(program).semantic
29  }
30
31  pub fn make_scoping(&self) -> Scoping {
32    self.program.with_dependent(|_owner, dep| {
33      Self::make_semantic(&dep.program, /*with_cfg*/ false).into_scoping()
34    })
35  }
36
37  pub fn make_symbol_table_and_scope_tree_with_semantic_builder<'a>(
38    &'a self,
39    semantic_builder: SemanticBuilder<'a>,
40  ) -> Scoping {
41    self.program.with_dependent::<'a, Scoping>(|_owner, dep| {
42      semantic_builder.build(&dep.program).semantic.into_scoping()
43    })
44  }
45}