refactor(traverse): enter node before entering scope (#4684)

Closes #4200.

Align `Traverse`'s behavior with `Visit` and `VisitMut`. For types with scopes, call `enter_*` before entering scope, and call `exit_*` after exiting scope.
This commit is contained in:
overlookmotel 2024-08-06 13:03:01 +00:00
parent 01d85de834
commit 83546d3230
6 changed files with 90 additions and 71 deletions

View file

@ -7,7 +7,10 @@ use oxc_ast::ast::*;
use oxc_semantic::SymbolFlags;
use oxc_span::{Atom, GetSpan, Span, SPAN};
use oxc_syntax::{
operator::AssignmentOperator, reference::ReferenceFlag, scope::ScopeFlags, symbol::SymbolId,
operator::AssignmentOperator,
reference::ReferenceFlag,
scope::{ScopeFlags, ScopeId},
symbol::SymbolId,
};
use oxc_traverse::TraverseCtx;
use rustc_hash::FxHashSet;
@ -419,7 +422,7 @@ impl<'a> TypeScriptAnnotations<'a> {
}
}
Self::replace_with_empty_block_if_ts(&mut stmt.consequent, ctx);
Self::replace_with_empty_block_if_ts(&mut stmt.consequent, ctx.current_scope_id(), ctx);
if stmt.alternate.as_ref().is_some_and(Statement::is_typescript_syntax) {
stmt.alternate = None;
@ -442,7 +445,8 @@ impl<'a> TypeScriptAnnotations<'a> {
stmt: &mut ForStatement<'a>,
ctx: &mut TraverseCtx<'a>,
) {
Self::replace_with_empty_block_if_ts(&mut stmt.body, ctx);
let scope_id = stmt.scope_id.get().unwrap_or(ctx.current_scope_id());
Self::replace_with_empty_block_if_ts(&mut stmt.body, scope_id, ctx);
}
pub fn transform_while_statement(
@ -450,7 +454,7 @@ impl<'a> TypeScriptAnnotations<'a> {
stmt: &mut WhileStatement<'a>,
ctx: &mut TraverseCtx<'a>,
) {
Self::replace_with_empty_block_if_ts(&mut stmt.body, ctx);
Self::replace_with_empty_block_if_ts(&mut stmt.body, ctx.current_scope_id(), ctx);
}
pub fn transform_do_while_statement(
@ -458,12 +462,16 @@ impl<'a> TypeScriptAnnotations<'a> {
stmt: &mut DoWhileStatement<'a>,
ctx: &mut TraverseCtx<'a>,
) {
Self::replace_with_empty_block_if_ts(&mut stmt.body, ctx);
Self::replace_with_empty_block_if_ts(&mut stmt.body, ctx.current_scope_id(), ctx);
}
fn replace_with_empty_block_if_ts(stmt: &mut Statement<'a>, ctx: &mut TraverseCtx<'a>) {
fn replace_with_empty_block_if_ts(
stmt: &mut Statement<'a>,
parent_scope_id: ScopeId,
ctx: &mut TraverseCtx<'a>,
) {
if stmt.is_typescript_syntax() {
let scope_id = ctx.create_scope_child_of_current(ScopeFlags::empty());
let scope_id = ctx.create_child_scope(parent_scope_id, ScopeFlags::empty());
let block = BlockStatement {
span: stmt.span(),
body: ctx.ast.vec(),

View file

@ -254,10 +254,9 @@ impl<'a> TypeScript<'a> {
}
if new_stmts.is_empty() {
// Delete the scope binding that `ctx.generate_uid_in_current_scope` created above,
// Delete the scope binding that `ctx.generate_uid` created above,
// as no binding is actually being created
let current_scope_id = ctx.current_scope_id();
ctx.scopes_mut().remove_binding(current_scope_id, &CompactStr::from(name.as_str()));
ctx.scopes_mut().remove_binding(scope_id, &CompactStr::from(name.as_str()));
return None;
}

View file

@ -69,7 +69,8 @@ function generateWalkForStruct(type, types) {
`\`ast\` attr says to enter scope before field '${enterFieldName}' `
+ `in '${type.name}', but that field is not visited`
);
if (scopeEnterField === visitedFields[0]) scopeEnterField = undefined;
} else {
scopeEnterField = visitedFields[0];
}
// TODO: Maybe this isn't quite right. `scope_id` fields are `Cell<Option<ScopeId>>`,
@ -93,18 +94,25 @@ function generateWalkForStruct(type, types) {
}
const fieldsCodes = visitedFields.map((field, index) => {
const fieldWalkName = `walk_${camelToSnake(field.innerTypeName)}`;
const fieldWalkName = `walk_${camelToSnake(field.innerTypeName)}`,
fieldCamelName = snakeToCamel(field.name);
const scopeCode = field === scopeEnterField ? enterScopeCode : '';
const retagCode = index === 0
? ''
: `ctx.retag_stack(AncestorType::${type.name}${snakeToCamel(field.name)});`;
const fieldCode = makeFieldCode(field);
let scopeCode = '';
if (field === scopeEnterField) {
scopeCode = enterScopeCode;
enterScopeCode = '';
let tagCode = '', retagCode = '';
if (index === 0) {
tagCode = `
ctx.push_stack(
Ancestor::${type.name}${fieldCamelName}(
ancestor::${type.name}Without${fieldCamelName}(node)
)
);
`;
} else {
retagCode = `ctx.retag_stack(AncestorType::${type.name}${fieldCamelName});`;
}
const fieldCode = makeFieldCode(field);
if (field.wrappers[0] === 'Option') {
let walkCode;
if (field.wrappers.length === 2 && field.wrappers[1] === 'Vec') {
@ -127,6 +135,7 @@ function generateWalkForStruct(type, types) {
return `
${scopeCode}
${tagCode}
if let Some(field) = &mut *(${fieldCode}) {
${retagCode}
${walkCode}
@ -159,7 +168,7 @@ function generateWalkForStruct(type, types) {
return `
${scopeCode}
${retagCode}
${tagCode || retagCode}
${walkVecCode}
`;
}
@ -167,7 +176,7 @@ function generateWalkForStruct(type, types) {
if (field.wrappers.length === 1 && field.wrappers[0] === 'Box') {
return `
${scopeCode}
${retagCode}
${tagCode || retagCode}
${fieldWalkName}(traverser, (&mut **(${fieldCode})) as *mut _, ctx);
`;
}
@ -176,23 +185,12 @@ function generateWalkForStruct(type, types) {
return `
${scopeCode}
${retagCode}
${tagCode || retagCode}
${fieldWalkName}(traverser, ${fieldCode}, ctx);
`;
});
if (visitedFields.length > 0) {
const field = visitedFields[0],
fieldCamelName = snakeToCamel(field.name);
fieldsCodes.unshift(`
ctx.push_stack(
Ancestor::${type.name}${fieldCamelName}(
ancestor::${type.name}Without${fieldCamelName}(node)
)
);
`);
fieldsCodes.push('ctx.pop_stack();');
}
if (visitedFields.length > 0) fieldsCodes.push('ctx.pop_stack();');
const typeSnakeName = camelToSnake(type.name);
return `
@ -201,12 +199,10 @@ function generateWalkForStruct(type, types) {
node: *mut ${type.rawName},
ctx: &mut TraverseCtx<'a>
) {
${enterScopeCode}
traverser.enter_${typeSnakeName}(&mut *node, ctx);
${fieldsCodes.join('\n')}
${enterScopeCode ? '' : exitScopeCode}
${exitScopeCode}
traverser.exit_${typeSnakeName}(&mut *node, ctx);
${enterScopeCode ? exitScopeCode : ''}
}
`.replace(/\n\s*\n+/g, '\n');
}

View file

@ -286,13 +286,22 @@ impl<'a> TraverseCtx<'a> {
self.scoping.find_scope_by_flags(finder)
}
/// Create new scope as child of provided scope.
///
/// `flags` provided are amended to inherit from parent scope's flags.
///
/// This is a shortcut for `ctx.scoping.create_child_scope`.
pub fn create_child_scope(&mut self, parent_id: ScopeId, flags: ScopeFlags) -> ScopeId {
self.scoping.create_child_scope(parent_id, flags)
}
/// Create new scope as child of current scope.
///
/// `flags` provided are amended to inherit from parent scope's flags.
///
/// This is a shortcut for `ctx.scoping.create_scope_child_of_current`.
pub fn create_scope_child_of_current(&mut self, flags: ScopeFlags) -> ScopeId {
self.scoping.create_scope_child_of_current(flags)
/// This is a shortcut for `ctx.scoping.create_child_scope_of_current`.
pub fn create_child_scope_of_current(&mut self, flags: ScopeFlags) -> ScopeId {
self.scoping.create_child_scope_of_current(flags)
}
/// Insert a scope into scope tree below a statement.

View file

@ -116,12 +116,19 @@ impl TraverseScoping {
})
}
/// Create new scope as child of provided scope.
///
/// `flags` provided are amended to inherit from parent scope's flags.
pub fn create_child_scope(&mut self, parent_id: ScopeId, flags: ScopeFlags) -> ScopeId {
let flags = self.scopes.get_new_scope_flags(flags, parent_id);
self.scopes.add_scope(parent_id, AstNodeId::DUMMY, flags)
}
/// Create new scope as child of current scope.
///
/// `flags` provided are amended to inherit from parent scope's flags.
pub fn create_scope_child_of_current(&mut self, flags: ScopeFlags) -> ScopeId {
let flags = self.scopes.get_new_scope_flags(flags, self.current_scope_id);
self.scopes.add_scope(self.current_scope_id, AstNodeId::DUMMY, flags)
pub fn create_child_scope_of_current(&mut self, flags: ScopeFlags) -> ScopeId {
self.create_child_scope(self.current_scope_id, flags)
}
/// Insert a scope into scope tree below a statement.
@ -162,7 +169,7 @@ impl TraverseScoping {
}
// Create new scope as child of parent
let new_scope_id = self.create_scope_child_of_current(flags);
let new_scope_id = self.create_child_scope_of_current(flags);
// Set scopes as children of new scope instead
for &child_id in child_scope_ids {

View file

@ -28,6 +28,7 @@ pub(crate) unsafe fn walk_program<'a, Tr: Traverse<'a>>(
node: *mut Program<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_program(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_PROGRAM_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -36,7 +37,6 @@ pub(crate) unsafe fn walk_program<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_program(&mut *node, ctx);
ctx.push_stack(Ancestor::ProgramHashbang(ancestor::ProgramWithoutHashbang(node)));
if let Some(field) =
&mut *((node as *mut u8).add(ancestor::OFFSET_PROGRAM_HASHBANG) as *mut Option<Hashbang>)
@ -57,10 +57,10 @@ pub(crate) unsafe fn walk_program<'a, Tr: Traverse<'a>>(
ctx,
);
ctx.pop_stack();
traverser.exit_program(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_program(&mut *node, ctx);
}
pub(crate) unsafe fn walk_expression<'a, Tr: Traverse<'a>>(
@ -1403,6 +1403,7 @@ pub(crate) unsafe fn walk_block_statement<'a, Tr: Traverse<'a>>(
node: *mut BlockStatement<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_block_statement(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_BLOCK_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -1411,7 +1412,6 @@ pub(crate) unsafe fn walk_block_statement<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_block_statement(&mut *node, ctx);
ctx.push_stack(Ancestor::BlockStatementBody(ancestor::BlockStatementWithoutBody(node)));
walk_statements(
traverser,
@ -1419,10 +1419,10 @@ pub(crate) unsafe fn walk_block_statement<'a, Tr: Traverse<'a>>(
ctx,
);
ctx.pop_stack();
traverser.exit_block_statement(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_block_statement(&mut *node, ctx);
}
pub(crate) unsafe fn walk_declaration<'a, Tr: Traverse<'a>>(
@ -1625,6 +1625,7 @@ pub(crate) unsafe fn walk_for_statement<'a, Tr: Traverse<'a>>(
node: *mut ForStatement<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_for_statement(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_FOR_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -1633,7 +1634,6 @@ pub(crate) unsafe fn walk_for_statement<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_for_statement(&mut *node, ctx);
ctx.push_stack(Ancestor::ForStatementInit(ancestor::ForStatementWithoutInit(node)));
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_FOR_STATEMENT_INIT)
as *mut Option<ForStatementInit>)
@ -1659,10 +1659,10 @@ pub(crate) unsafe fn walk_for_statement<'a, Tr: Traverse<'a>>(
ctx,
);
ctx.pop_stack();
traverser.exit_for_statement(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_for_statement(&mut *node, ctx);
}
pub(crate) unsafe fn walk_for_statement_init<'a, Tr: Traverse<'a>>(
@ -1731,6 +1731,7 @@ pub(crate) unsafe fn walk_for_in_statement<'a, Tr: Traverse<'a>>(
node: *mut ForInStatement<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_for_in_statement(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_FOR_IN_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -1739,7 +1740,6 @@ pub(crate) unsafe fn walk_for_in_statement<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_for_in_statement(&mut *node, ctx);
ctx.push_stack(Ancestor::ForInStatementLeft(ancestor::ForInStatementWithoutLeft(node)));
walk_for_statement_left(
traverser,
@ -1759,10 +1759,10 @@ pub(crate) unsafe fn walk_for_in_statement<'a, Tr: Traverse<'a>>(
ctx,
);
ctx.pop_stack();
traverser.exit_for_in_statement(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_for_in_statement(&mut *node, ctx);
}
pub(crate) unsafe fn walk_for_statement_left<'a, Tr: Traverse<'a>>(
@ -1800,6 +1800,7 @@ pub(crate) unsafe fn walk_for_of_statement<'a, Tr: Traverse<'a>>(
node: *mut ForOfStatement<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_for_of_statement(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_FOR_OF_STATEMENT_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -1808,7 +1809,6 @@ pub(crate) unsafe fn walk_for_of_statement<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_for_of_statement(&mut *node, ctx);
ctx.push_stack(Ancestor::ForOfStatementLeft(ancestor::ForOfStatementWithoutLeft(node)));
walk_for_statement_left(
traverser,
@ -1828,10 +1828,10 @@ pub(crate) unsafe fn walk_for_of_statement<'a, Tr: Traverse<'a>>(
ctx,
);
ctx.pop_stack();
traverser.exit_for_of_statement(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_for_of_statement(&mut *node, ctx);
}
pub(crate) unsafe fn walk_continue_statement<'a, Tr: Traverse<'a>>(
@ -2036,6 +2036,7 @@ pub(crate) unsafe fn walk_catch_clause<'a, Tr: Traverse<'a>>(
node: *mut CatchClause<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_catch_clause(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_CATCH_CLAUSE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -2044,7 +2045,6 @@ pub(crate) unsafe fn walk_catch_clause<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_catch_clause(&mut *node, ctx);
ctx.push_stack(Ancestor::CatchClauseParam(ancestor::CatchClauseWithoutParam(node)));
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_CATCH_CLAUSE_PARAM)
as *mut Option<CatchParameter>)
@ -2059,10 +2059,10 @@ pub(crate) unsafe fn walk_catch_clause<'a, Tr: Traverse<'a>>(
ctx,
);
ctx.pop_stack();
traverser.exit_catch_clause(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_catch_clause(&mut *node, ctx);
}
pub(crate) unsafe fn walk_catch_parameter<'a, Tr: Traverse<'a>>(
@ -2253,6 +2253,7 @@ pub(crate) unsafe fn walk_function<'a, Tr: Traverse<'a>>(
node: *mut Function<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_function(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_FUNCTION_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -2261,7 +2262,6 @@ pub(crate) unsafe fn walk_function<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_function(&mut *node, ctx);
ctx.push_stack(Ancestor::FunctionId(ancestor::FunctionWithoutId(node)));
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_FUNCTION_ID)
as *mut Option<BindingIdentifier>)
@ -2300,10 +2300,10 @@ pub(crate) unsafe fn walk_function<'a, Tr: Traverse<'a>>(
walk_function_body(traverser, (&mut **field) as *mut _, ctx);
}
ctx.pop_stack();
traverser.exit_function(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_function(&mut *node, ctx);
}
pub(crate) unsafe fn walk_formal_parameters<'a, Tr: Traverse<'a>>(
@ -2382,6 +2382,7 @@ pub(crate) unsafe fn walk_arrow_function_expression<'a, Tr: Traverse<'a>>(
node: *mut ArrowFunctionExpression<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_arrow_function_expression(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8)
.add(ancestor::OFFSET_ARROW_FUNCTION_EXPRESSION_SCOPE_ID)
@ -2391,7 +2392,6 @@ pub(crate) unsafe fn walk_arrow_function_expression<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_arrow_function_expression(&mut *node, ctx);
ctx.push_stack(Ancestor::ArrowFunctionExpressionTypeParameters(
ancestor::ArrowFunctionExpressionWithoutTypeParameters(node),
));
@ -2423,10 +2423,10 @@ pub(crate) unsafe fn walk_arrow_function_expression<'a, Tr: Traverse<'a>>(
ctx,
);
ctx.pop_stack();
traverser.exit_arrow_function_expression(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_arrow_function_expression(&mut *node, ctx);
}
pub(crate) unsafe fn walk_yield_expression<'a, Tr: Traverse<'a>>(
@ -2640,6 +2640,7 @@ pub(crate) unsafe fn walk_static_block<'a, Tr: Traverse<'a>>(
node: *mut StaticBlock<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_static_block(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_STATIC_BLOCK_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -2648,7 +2649,6 @@ pub(crate) unsafe fn walk_static_block<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_static_block(&mut *node, ctx);
ctx.push_stack(Ancestor::StaticBlockBody(ancestor::StaticBlockWithoutBody(node)));
walk_statements(
traverser,
@ -2656,10 +2656,10 @@ pub(crate) unsafe fn walk_static_block<'a, Tr: Traverse<'a>>(
ctx,
);
ctx.pop_stack();
traverser.exit_static_block(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_static_block(&mut *node, ctx);
}
pub(crate) unsafe fn walk_module_declaration<'a, Tr: Traverse<'a>>(
@ -3928,6 +3928,7 @@ pub(crate) unsafe fn walk_ts_conditional_type<'a, Tr: Traverse<'a>>(
node: *mut TSConditionalType<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_ts_conditional_type(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_TS_CONDITIONAL_TYPE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -3936,7 +3937,6 @@ pub(crate) unsafe fn walk_ts_conditional_type<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_ts_conditional_type(&mut *node, ctx);
ctx.push_stack(Ancestor::TSConditionalTypeCheckType(
ancestor::TSConditionalTypeWithoutCheckType(node),
));
@ -3964,10 +3964,10 @@ pub(crate) unsafe fn walk_ts_conditional_type<'a, Tr: Traverse<'a>>(
ctx,
);
ctx.pop_stack();
traverser.exit_ts_conditional_type(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_ts_conditional_type(&mut *node, ctx);
}
pub(crate) unsafe fn walk_ts_union_type<'a, Tr: Traverse<'a>>(
@ -4734,6 +4734,7 @@ pub(crate) unsafe fn walk_ts_method_signature<'a, Tr: Traverse<'a>>(
node: *mut TSMethodSignature<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_ts_method_signature(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_TS_METHOD_SIGNATURE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -4742,7 +4743,6 @@ pub(crate) unsafe fn walk_ts_method_signature<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_ts_method_signature(&mut *node, ctx);
ctx.push_stack(Ancestor::TSMethodSignatureKey(ancestor::TSMethodSignatureWithoutKey(node)));
walk_property_key(
traverser,
@ -4778,10 +4778,10 @@ pub(crate) unsafe fn walk_ts_method_signature<'a, Tr: Traverse<'a>>(
walk_ts_type_parameter_declaration(traverser, (&mut **field) as *mut _, ctx);
}
ctx.pop_stack();
traverser.exit_ts_method_signature(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_ts_method_signature(&mut *node, ctx);
}
pub(crate) unsafe fn walk_ts_construct_signature_declaration<'a, Tr: Traverse<'a>>(
@ -4789,6 +4789,7 @@ pub(crate) unsafe fn walk_ts_construct_signature_declaration<'a, Tr: Traverse<'a
node: *mut TSConstructSignatureDeclaration<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_ts_construct_signature_declaration(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8)
.add(ancestor::OFFSET_TS_CONSTRUCT_SIGNATURE_DECLARATION_SCOPE_ID)
@ -4798,7 +4799,6 @@ pub(crate) unsafe fn walk_ts_construct_signature_declaration<'a, Tr: Traverse<'a
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_ts_construct_signature_declaration(&mut *node, ctx);
ctx.push_stack(Ancestor::TSConstructSignatureDeclarationParams(
ancestor::TSConstructSignatureDeclarationWithoutParams(node),
));
@ -4823,10 +4823,10 @@ pub(crate) unsafe fn walk_ts_construct_signature_declaration<'a, Tr: Traverse<'a
walk_ts_type_parameter_declaration(traverser, (&mut **field) as *mut _, ctx);
}
ctx.pop_stack();
traverser.exit_ts_construct_signature_declaration(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_ts_construct_signature_declaration(&mut *node, ctx);
}
pub(crate) unsafe fn walk_ts_index_signature_name<'a, Tr: Traverse<'a>>(
@ -5262,6 +5262,7 @@ pub(crate) unsafe fn walk_ts_mapped_type<'a, Tr: Traverse<'a>>(
node: *mut TSMappedType<'a>,
ctx: &mut TraverseCtx<'a>,
) {
traverser.enter_ts_mapped_type(&mut *node, ctx);
let mut previous_scope_id = None;
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_TS_MAPPED_TYPE_SCOPE_ID)
as *mut Cell<Option<ScopeId>>))
@ -5270,7 +5271,6 @@ pub(crate) unsafe fn walk_ts_mapped_type<'a, Tr: Traverse<'a>>(
previous_scope_id = Some(ctx.current_scope_id());
ctx.set_current_scope_id(scope_id);
}
traverser.enter_ts_mapped_type(&mut *node, ctx);
ctx.push_stack(Ancestor::TSMappedTypeTypeParameter(
ancestor::TSMappedTypeWithoutTypeParameter(node),
));
@ -5294,10 +5294,10 @@ pub(crate) unsafe fn walk_ts_mapped_type<'a, Tr: Traverse<'a>>(
walk_ts_type(traverser, field as *mut _, ctx);
}
ctx.pop_stack();
traverser.exit_ts_mapped_type(&mut *node, ctx);
if let Some(previous_scope_id) = previous_scope_id {
ctx.set_current_scope_id(previous_scope_id);
}
traverser.exit_ts_mapped_type(&mut *node, ctx);
}
pub(crate) unsafe fn walk_ts_template_literal_type<'a, Tr: Traverse<'a>>(