feat(traverse): add generate_uid_in_current_hoist_scope method (#7423)

Add an API to handle variable hoisting.
This commit is contained in:
Dunqing 2024-11-26 11:21:35 +00:00
parent 4f23689e79
commit 9c9deaeffe
4 changed files with 186 additions and 127 deletions

View file

@ -109,11 +109,26 @@ function generateWalkForStruct(type, types) {
// but we don't take that into account.
// Visitor should not do that though, so maybe it's OK.
// In final version, we should not make `scope_id` fields `Cell`s to prevent this.
enterScopeCode = `
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id((*(${makeFieldCode(scopeIdField)})).get().unwrap());
let current_scope_id = (*(${makeFieldCode(scopeIdField)})).get().unwrap();
ctx.set_current_scope_id(current_scope_id);
`;
exitScopeCode = `ctx.set_current_scope_id(previous_scope_id);`;
exitScopeCode = 'ctx.set_current_scope_id(previous_scope_id);';
// const Var = Self::Top.bits() | Self::Function.bits() | Self::ClassStaticBlock.bits() | Self::TsModuleBlock.bits();
// `Function` type is a special case as its flags are set dynamically depending on the parent.
let isVarHoistingScope = type.name == 'Function' ||
['Top', 'Function', 'ClassStaticBlock', 'TsModuleBlock'].some(flag => scopeArgs.flags.includes(flag));
if (isVarHoistingScope) {
enterScopeCode += `
let previous_hoist_scope_id = ctx.current_hoist_scope_id();
ctx.set_current_hoist_scope_id(current_scope_id);
`;
exitScopeCode += 'ctx.set_current_hoist_scope_id(previous_hoist_scope_id);';
}
}
const fieldsCodes = visitedFields.map((field, index) => {

View file

@ -3,8 +3,8 @@ use oxc_ast::{
ast::{Expression, IdentifierReference, Statement},
AstBuilder,
};
use oxc_semantic::{NodeId, ScopeTree, SymbolTable};
use oxc_span::{Atom, CompactStr, Span, SPAN};
use oxc_semantic::{ScopeTree, SymbolTable};
use oxc_span::{Atom, CompactStr, Span};
use oxc_syntax::{
reference::{ReferenceFlags, ReferenceId},
scope::{ScopeFlags, ScopeId},
@ -186,6 +186,14 @@ impl<'a> TraverseCtx<'a> {
self.scoping.current_scope_id()
}
/// Get current var hoisting scope ID.
///
/// Shortcut for `ctx.scoping.current_hoist_scope_id`.
#[inline]
pub fn current_hoist_scope_id(&self) -> ScopeId {
self.scoping.current_hoist_scope_id()
}
/// Get current scope flags.
///
/// Shortcut for `ctx.scoping.current_scope_flags`.
@ -356,12 +364,7 @@ impl<'a> TraverseCtx<'a> {
// Get name for UID
let name = self.generate_uid_name(name);
let name_atom = self.ast.atom(&name);
// Add binding to scope
let symbol_id =
self.symbols_mut().create_symbol(SPAN, name.clone(), flags, scope_id, NodeId::DUMMY);
self.scopes_mut().add_binding(scope_id, name, symbol_id);
let symbol_id = self.scoping.add_binding(name, scope_id, flags);
BoundIdentifier::new(name_atom, symbol_id)
}
@ -421,6 +424,15 @@ impl<'a> TraverseCtx<'a> {
self.generate_uid_based_on_node(node, self.current_scope_id(), flags)
}
/// Generate UID in current hoist scope.
///
/// See also comments on [`TraverseScoping::generate_uid_name`] for important information
/// on how UIDs are generated. There are some potential "gotchas".
#[inline]
pub fn generate_uid_in_current_hoist_scope(&mut self, name: &str) -> BoundIdentifier<'a> {
self.generate_uid(name, self.current_hoist_scope_id(), SymbolFlags::FunctionScopedVariable)
}
/// Create a reference bound to a `SymbolId`.
///
/// This is a shortcut for `ctx.scoping.create_bound_reference`.
@ -623,4 +635,10 @@ impl<'a> TraverseCtx<'a> {
pub(crate) fn set_current_scope_id(&mut self, scope_id: ScopeId) {
self.scoping.set_current_scope_id(scope_id);
}
/// Shortcut for `ctx.scoping.set_current_hoist_scope_id`, to make `walk_*` methods less verbose.
#[inline]
pub(crate) fn set_current_hoist_scope_id(&mut self, scope_id: ScopeId) {
self.scoping.set_current_hoist_scope_id(scope_id);
}
}

View file

@ -26,6 +26,7 @@ pub struct TraverseScoping {
symbols: SymbolTable,
uid_names: Option<FxHashSet<CompactStr>>,
current_scope_id: ScopeId,
current_hoist_scope_id: ScopeId,
}
// Public methods
@ -40,6 +41,12 @@ impl TraverseScoping {
self.current_scope_id
}
/// Get current var hoisting scope ID
#[inline]
pub(crate) fn current_hoist_scope_id(&self) -> ScopeId {
self.current_hoist_scope_id
}
/// Get current scope flags
#[inline]
pub fn current_scope_flags(&self) -> ScopeFlags {
@ -164,6 +171,21 @@ impl TraverseScoping {
self.scopes.delete_scope(scope_id);
}
/// Add binding to [`ScopeTree`] and [`SymbolTable`].
#[inline]
pub(crate) fn add_binding(
&mut self,
name: CompactStr,
scope_id: ScopeId,
flags: SymbolFlags,
) -> SymbolId {
let symbol_id =
self.symbols.create_symbol(SPAN, name.clone(), flags, scope_id, NodeId::DUMMY);
self.scopes.add_binding(scope_id, name, symbol_id);
symbol_id
}
/// Generate binding.
///
/// Creates a symbol with the provided name and flags and adds it to the specified scope.
@ -173,13 +195,7 @@ impl TraverseScoping {
scope_id: ScopeId,
flags: SymbolFlags,
) -> BoundIdentifier<'a> {
let owned_name = name.to_compact_str();
// Add binding to scope
let symbol_id =
self.symbols.create_symbol(SPAN, owned_name.clone(), flags, scope_id, NodeId::DUMMY);
self.scopes.add_binding(scope_id, owned_name, symbol_id);
let symbol_id = self.add_binding(name.to_compact_str(), scope_id, flags);
BoundIdentifier::new(name, symbol_id)
}
@ -386,8 +402,9 @@ impl TraverseScoping {
scopes,
symbols,
uid_names: None,
// Dummy value. Immediately overwritten in `walk_program`.
// Dummy values. Both immediately overwritten in `walk_program`.
current_scope_id: ScopeId::new(0),
current_hoist_scope_id: ScopeId::new(0),
}
}
@ -397,6 +414,12 @@ impl TraverseScoping {
self.current_scope_id = scope_id;
}
/// Set current hoist scope ID
#[inline]
pub(crate) fn set_current_hoist_scope_id(&mut self, scope_id: ScopeId) {
self.current_hoist_scope_id = scope_id;
}
/// Get `uid_names`.
///
/// Iterate through all symbols and unresolved references in AST and identify any var names

View file

@ -32,11 +32,13 @@ pub(crate) unsafe fn walk_program<'a, Tr: Traverse<'a>>(
) {
traverser.enter_program(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_PROGRAM_SCOPE_ID) as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_PROGRAM_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let previous_hoist_scope_id = ctx.current_hoist_scope_id();
ctx.set_current_hoist_scope_id(current_scope_id);
let pop_token = ctx
.push_stack(Ancestor::ProgramHashbang(ancestor::ProgramWithoutHashbang(node, PhantomData)));
if let Some(field) =
@ -59,6 +61,7 @@ pub(crate) unsafe fn walk_program<'a, Tr: Traverse<'a>>(
);
ctx.pop_stack(pop_token);
ctx.set_current_scope_id(previous_scope_id);
ctx.set_current_hoist_scope_id(previous_hoist_scope_id);
traverser.exit_program(&mut *node, ctx);
}
@ -1417,12 +1420,11 @@ pub(crate) unsafe fn walk_block_statement<'a, Tr: Traverse<'a>>(
) {
traverser.enter_block_statement(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_BLOCK_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_BLOCK_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let pop_token = ctx.push_stack(Ancestor::BlockStatementBody(
ancestor::BlockStatementWithoutBody(node, PhantomData),
));
@ -1623,12 +1625,11 @@ pub(crate) unsafe fn walk_for_statement<'a, Tr: Traverse<'a>>(
) {
traverser.enter_for_statement(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_FOR_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_FOR_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let pop_token = ctx.push_stack(Ancestor::ForStatementInit(ancestor::ForStatementWithoutInit(
node,
PhantomData,
@ -1726,12 +1727,11 @@ pub(crate) unsafe fn walk_for_in_statement<'a, Tr: Traverse<'a>>(
) {
traverser.enter_for_in_statement(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_FOR_IN_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_FOR_IN_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let pop_token = ctx.push_stack(Ancestor::ForInStatementLeft(
ancestor::ForInStatementWithoutLeft(node, PhantomData),
));
@ -1791,12 +1791,11 @@ pub(crate) unsafe fn walk_for_of_statement<'a, Tr: Traverse<'a>>(
) {
traverser.enter_for_of_statement(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_FOR_OF_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_FOR_OF_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let pop_token = ctx.push_stack(Ancestor::ForOfStatementLeft(
ancestor::ForOfStatementWithoutLeft(node, PhantomData),
));
@ -1915,12 +1914,11 @@ pub(crate) unsafe fn walk_switch_statement<'a, Tr: Traverse<'a>>(
ctx,
);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_SWITCH_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_SWITCH_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
ctx.retag_stack(AncestorType::SwitchStatementCases);
for item in (*((node as *mut u8).add(ancestor::OFFSET_SWITCH_STATEMENT_CASES)
as *mut Vec<SwitchCase>))
@ -2036,12 +2034,11 @@ pub(crate) unsafe fn walk_catch_clause<'a, Tr: Traverse<'a>>(
) {
traverser.enter_catch_clause(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_CATCH_CLAUSE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_CATCH_CLAUSE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let pop_token = ctx.push_stack(Ancestor::CatchClauseParam(ancestor::CatchClauseWithoutParam(
node,
PhantomData,
@ -2263,12 +2260,13 @@ pub(crate) unsafe fn walk_function<'a, Tr: Traverse<'a>>(
) {
traverser.enter_function(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_FUNCTION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_FUNCTION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let previous_hoist_scope_id = ctx.current_hoist_scope_id();
ctx.set_current_hoist_scope_id(current_scope_id);
let pop_token =
ctx.push_stack(Ancestor::FunctionId(ancestor::FunctionWithoutId(node, PhantomData)));
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_FUNCTION_ID)
@ -2309,6 +2307,7 @@ pub(crate) unsafe fn walk_function<'a, Tr: Traverse<'a>>(
}
ctx.pop_stack(pop_token);
ctx.set_current_scope_id(previous_scope_id);
ctx.set_current_hoist_scope_id(previous_hoist_scope_id);
traverser.exit_function(&mut *node, ctx);
}
@ -2394,12 +2393,14 @@ pub(crate) unsafe fn walk_arrow_function_expression<'a, Tr: Traverse<'a>>(
) {
traverser.enter_arrow_function_expression(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_ARROW_FUNCTION_EXPRESSION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8)
.add(ancestor::OFFSET_ARROW_FUNCTION_EXPRESSION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let previous_hoist_scope_id = ctx.current_hoist_scope_id();
ctx.set_current_hoist_scope_id(current_scope_id);
let pop_token = ctx.push_stack(Ancestor::ArrowFunctionExpressionTypeParameters(
ancestor::ArrowFunctionExpressionWithoutTypeParameters(node, PhantomData),
));
@ -2432,6 +2433,7 @@ pub(crate) unsafe fn walk_arrow_function_expression<'a, Tr: Traverse<'a>>(
);
ctx.pop_stack(pop_token);
ctx.set_current_scope_id(previous_scope_id);
ctx.set_current_hoist_scope_id(previous_hoist_scope_id);
traverser.exit_arrow_function_expression(&mut *node, ctx);
}
@ -2473,11 +2475,11 @@ pub(crate) unsafe fn walk_class<'a, Tr: Traverse<'a>>(
walk_binding_identifier(traverser, field as *mut _, ctx);
}
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_CLASS_SCOPE_ID) as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_CLASS_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_CLASS_TYPE_PARAMETERS)
as *mut Option<Box<TSTypeParameterDeclaration>>)
{
@ -2646,12 +2648,13 @@ pub(crate) unsafe fn walk_static_block<'a, Tr: Traverse<'a>>(
) {
traverser.enter_static_block(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_STATIC_BLOCK_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_STATIC_BLOCK_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let previous_hoist_scope_id = ctx.current_hoist_scope_id();
ctx.set_current_hoist_scope_id(current_scope_id);
let pop_token = ctx
.push_stack(Ancestor::StaticBlockBody(ancestor::StaticBlockWithoutBody(node, PhantomData)));
walk_statements(
@ -2661,6 +2664,7 @@ pub(crate) unsafe fn walk_static_block<'a, Tr: Traverse<'a>>(
);
ctx.pop_stack(pop_token);
ctx.set_current_scope_id(previous_scope_id);
ctx.set_current_hoist_scope_id(previous_hoist_scope_id);
traverser.exit_static_block(&mut *node, ctx);
}
@ -3670,12 +3674,11 @@ pub(crate) unsafe fn walk_ts_enum_declaration<'a, Tr: Traverse<'a>>(
ctx,
);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_TS_ENUM_DECLARATION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_TS_ENUM_DECLARATION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
ctx.retag_stack(AncestorType::TSEnumDeclarationMembers);
for item in (*((node as *mut u8).add(ancestor::OFFSET_TS_ENUM_DECLARATION_MEMBERS)
as *mut Vec<TSEnumMember>))
@ -3919,12 +3922,11 @@ pub(crate) unsafe fn walk_ts_conditional_type<'a, Tr: Traverse<'a>>(
ctx,
);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_TS_CONDITIONAL_TYPE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_TS_CONDITIONAL_TYPE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
ctx.retag_stack(AncestorType::TSConditionalTypeExtendsType);
walk_ts_type(
traverser,
@ -4476,12 +4478,12 @@ pub(crate) unsafe fn walk_ts_type_alias_declaration<'a, Tr: Traverse<'a>>(
ctx,
);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_TS_TYPE_ALIAS_DECLARATION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8)
.add(ancestor::OFFSET_TS_TYPE_ALIAS_DECLARATION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
if let Some(field) = &mut *((node as *mut u8)
.add(ancestor::OFFSET_TS_TYPE_ALIAS_DECLARATION_TYPE_PARAMETERS)
as *mut Option<Box<TSTypeParameterDeclaration>>)
@ -4542,12 +4544,12 @@ pub(crate) unsafe fn walk_ts_interface_declaration<'a, Tr: Traverse<'a>>(
ctx,
);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_TS_INTERFACE_DECLARATION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8)
.add(ancestor::OFFSET_TS_INTERFACE_DECLARATION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
if let Some(field) = &mut *((node as *mut u8)
.add(ancestor::OFFSET_TS_INTERFACE_DECLARATION_EXTENDS)
as *mut Option<Vec<TSInterfaceHeritage>>)
@ -4719,12 +4721,11 @@ pub(crate) unsafe fn walk_ts_method_signature<'a, Tr: Traverse<'a>>(
) {
traverser.enter_ts_method_signature(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_TS_METHOD_SIGNATURE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_TS_METHOD_SIGNATURE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let pop_token = ctx.push_stack(Ancestor::TSMethodSignatureKey(
ancestor::TSMethodSignatureWithoutKey(node, PhantomData),
));
@ -4773,12 +4774,12 @@ pub(crate) unsafe fn walk_ts_construct_signature_declaration<'a, Tr: Traverse<'a
) {
traverser.enter_ts_construct_signature_declaration(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_TS_CONSTRUCT_SIGNATURE_DECLARATION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8)
.add(ancestor::OFFSET_TS_CONSTRUCT_SIGNATURE_DECLARATION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let pop_token = ctx.push_stack(Ancestor::TSConstructSignatureDeclarationTypeParameters(
ancestor::TSConstructSignatureDeclarationWithoutTypeParameters(node, PhantomData),
));
@ -4908,12 +4909,14 @@ pub(crate) unsafe fn walk_ts_module_declaration<'a, Tr: Traverse<'a>>(
ctx,
);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
let current_scope_id =
(*((node as *mut u8).add(ancestor::OFFSET_TS_MODULE_DECLARATION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let previous_hoist_scope_id = ctx.current_hoist_scope_id();
ctx.set_current_hoist_scope_id(current_scope_id);
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_TS_MODULE_DECLARATION_BODY)
as *mut Option<TSModuleDeclarationBody>)
{
@ -4922,6 +4925,7 @@ pub(crate) unsafe fn walk_ts_module_declaration<'a, Tr: Traverse<'a>>(
}
ctx.pop_stack(pop_token);
ctx.set_current_scope_id(previous_scope_id);
ctx.set_current_hoist_scope_id(previous_hoist_scope_id);
traverser.exit_ts_module_declaration(&mut *node, ctx);
}
@ -5248,12 +5252,11 @@ pub(crate) unsafe fn walk_ts_mapped_type<'a, Tr: Traverse<'a>>(
) {
traverser.enter_ts_mapped_type(&mut *node, ctx);
let previous_scope_id = ctx.current_scope_id();
ctx.set_current_scope_id(
(*((node as *mut u8).add(ancestor::OFFSET_TS_MAPPED_TYPE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap(),
);
let current_scope_id = (*((node as *mut u8).add(ancestor::OFFSET_TS_MAPPED_TYPE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
.get()
.unwrap();
ctx.set_current_scope_id(current_scope_id);
let pop_token = ctx.push_stack(Ancestor::TSMappedTypeTypeParameter(
ancestor::TSMappedTypeWithoutTypeParameter(node, PhantomData),
));