mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(ast): move scope from TSModuleBlock to TSModuleDeclaration (#3488)
Closes #3471. Remove scope from `TSModuleBlock` and add scope to `TSModuleDeclaration` instead.
This commit is contained in:
parent
9c3d1631a4
commit
55bbde2888
8 changed files with 82 additions and 54 deletions
|
|
@ -868,8 +868,8 @@ pub enum TSTypePredicateName<'a> {
|
|||
This(TSThisType),
|
||||
}
|
||||
|
||||
#[visited_node]
|
||||
#[derive(Debug, Hash)]
|
||||
#[visited_node(scope(ScopeFlags::TsModuleBlock), enter_scope_before(body))]
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))]
|
||||
pub struct TSModuleDeclaration<'a> {
|
||||
|
|
@ -889,6 +889,28 @@ pub struct TSModuleDeclaration<'a> {
|
|||
pub kind: TSModuleDeclarationKind,
|
||||
/// Valid Modifiers: `declare`, `export`
|
||||
pub modifiers: Modifiers<'a>,
|
||||
pub scope_id: Cell<Option<ScopeId>>,
|
||||
}
|
||||
|
||||
impl<'a> TSModuleDeclaration<'a> {
|
||||
pub fn new(
|
||||
span: Span,
|
||||
id: TSModuleDeclarationName<'a>,
|
||||
body: Option<TSModuleDeclarationBody<'a>>,
|
||||
kind: TSModuleDeclarationKind,
|
||||
modifiers: Modifiers<'a>,
|
||||
) -> Self {
|
||||
Self { span, id, body, kind, modifiers, scope_id: Cell::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Hash for TSModuleDeclaration<'a> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.id.hash(state);
|
||||
self.body.hash(state);
|
||||
self.kind.hash(state);
|
||||
self.modifiers.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
|
|
@ -931,27 +953,14 @@ pub enum TSModuleDeclarationBody<'a> {
|
|||
TSModuleBlock(Box<'a, TSModuleBlock<'a>>),
|
||||
}
|
||||
|
||||
#[visited_node(scope(ScopeFlags::TsModuleBlock))]
|
||||
#[derive(Debug)]
|
||||
#[visited_node]
|
||||
#[derive(Debug, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))]
|
||||
#[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))]
|
||||
pub struct TSModuleBlock<'a> {
|
||||
#[cfg_attr(feature = "serialize", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub body: Vec<'a, Statement<'a>>,
|
||||
pub scope_id: Cell<Option<ScopeId>>,
|
||||
}
|
||||
|
||||
impl<'a> TSModuleBlock<'a> {
|
||||
pub fn new(span: Span, body: Vec<'a, Statement<'a>>) -> Self {
|
||||
Self { span, body, scope_id: Cell::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Hash for TSModuleBlock<'a> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.body.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
#[visited_node]
|
||||
|
|
|
|||
|
|
@ -1495,7 +1495,7 @@ impl<'a> AstBuilder<'a> {
|
|||
kind: TSModuleDeclarationKind,
|
||||
modifiers: Modifiers<'a>,
|
||||
) -> Box<'a, TSModuleDeclaration<'a>> {
|
||||
self.alloc(TSModuleDeclaration { span, id, body, kind, modifiers })
|
||||
self.alloc(TSModuleDeclaration::new(span, id, body, kind, modifiers))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -1734,7 +1734,7 @@ impl<'a> AstBuilder<'a> {
|
|||
span: Span,
|
||||
body: Vec<'a, Statement<'a>>,
|
||||
) -> Box<'a, TSModuleBlock<'a>> {
|
||||
self.alloc(TSModuleBlock::new(span, body))
|
||||
self.alloc(TSModuleBlock { span, body })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -2579,6 +2579,7 @@ pub mod walk {
|
|||
TSModuleDeclarationName::Identifier(ident) => visitor.visit_identifier_name(ident),
|
||||
TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit),
|
||||
}
|
||||
visitor.enter_scope(ScopeFlags::TsModuleBlock);
|
||||
match &decl.body {
|
||||
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
||||
visitor.visit_ts_module_declaration(decl);
|
||||
|
|
@ -2588,16 +2589,15 @@ pub mod walk {
|
|||
}
|
||||
None => {}
|
||||
}
|
||||
visitor.leave_scope();
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
pub fn walk_ts_module_block<'a, V: Visit<'a>>(visitor: &mut V, block: &TSModuleBlock<'a>) {
|
||||
let kind = AstKind::TSModuleBlock(visitor.alloc(block));
|
||||
visitor.enter_scope(ScopeFlags::TsModuleBlock);
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_statements(&block.body);
|
||||
visitor.leave_node(kind);
|
||||
visitor.leave_scope();
|
||||
}
|
||||
|
||||
pub fn walk_ts_type_alias_declaration<'a, V: Visit<'a>>(
|
||||
|
|
|
|||
|
|
@ -2728,6 +2728,7 @@ pub mod walk_mut {
|
|||
TSModuleDeclarationName::Identifier(ident) => visitor.visit_identifier_name(ident),
|
||||
TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit),
|
||||
}
|
||||
visitor.enter_scope(ScopeFlags::TsModuleBlock);
|
||||
match &mut decl.body {
|
||||
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
||||
visitor.visit_ts_module_declaration(decl);
|
||||
|
|
@ -2737,6 +2738,7 @@ pub mod walk_mut {
|
|||
}
|
||||
None => {}
|
||||
}
|
||||
visitor.leave_scope();
|
||||
visitor.leave_node(kind);
|
||||
}
|
||||
|
||||
|
|
@ -2745,11 +2747,9 @@ pub mod walk_mut {
|
|||
block: &mut TSModuleBlock<'a>,
|
||||
) {
|
||||
let kind = AstType::TSModuleBlock;
|
||||
visitor.enter_scope(ScopeFlags::TsModuleBlock);
|
||||
visitor.enter_node(kind);
|
||||
visitor.visit_statements(&mut block.body);
|
||||
visitor.leave_node(kind);
|
||||
visitor.leave_scope();
|
||||
}
|
||||
|
||||
pub fn walk_ts_type_alias_declaration_mut<'a, V: VisitMut<'a>>(
|
||||
|
|
|
|||
|
|
@ -1772,14 +1772,26 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
|
|||
self.leave_node(kind);
|
||||
}
|
||||
|
||||
fn visit_ts_module_block(&mut self, block: &TSModuleBlock<'a>) {
|
||||
let kind = AstKind::TSModuleBlock(self.alloc(block));
|
||||
self.enter_scope(ScopeFlags::TsModuleBlock);
|
||||
block.scope_id.set(Some(self.current_scope_id));
|
||||
fn visit_ts_module_declaration(&mut self, decl: &TSModuleDeclaration<'a>) {
|
||||
let kind = AstKind::TSModuleDeclaration(self.alloc(decl));
|
||||
self.enter_node(kind);
|
||||
self.visit_statements(&block.body);
|
||||
self.leave_node(kind);
|
||||
match &decl.id {
|
||||
TSModuleDeclarationName::Identifier(ident) => self.visit_identifier_name(ident),
|
||||
TSModuleDeclarationName::StringLiteral(lit) => self.visit_string_literal(lit),
|
||||
}
|
||||
self.enter_scope(ScopeFlags::TsModuleBlock);
|
||||
decl.scope_id.set(Some(self.current_scope_id));
|
||||
match &decl.body {
|
||||
Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => {
|
||||
self.visit_ts_module_declaration(decl);
|
||||
}
|
||||
Some(TSModuleDeclarationBody::TSModuleBlock(block)) => {
|
||||
self.visit_ts_module_block(block);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
self.leave_scope();
|
||||
self.leave_node(kind);
|
||||
}
|
||||
|
||||
fn visit_ts_type_parameter(&mut self, ty: &TSTypeParameter<'a>) {
|
||||
|
|
|
|||
|
|
@ -144,14 +144,11 @@ impl<'a> TypeScript<'a> {
|
|||
);
|
||||
|
||||
// Reuse TSModuleBlock's scope id in transformed function.
|
||||
let mut scope_id = None;
|
||||
let scope_id = decl.scope_id.get();
|
||||
|
||||
let namespace_top_level = if let Some(body) = decl.body {
|
||||
match body {
|
||||
TSModuleDeclarationBody::TSModuleBlock(block) => {
|
||||
scope_id = block.scope_id.get();
|
||||
block.unbox().body
|
||||
}
|
||||
TSModuleDeclarationBody::TSModuleBlock(block) => block.unbox().body,
|
||||
// We handle `namespace X.Y {}` as if it was
|
||||
// namespace X {
|
||||
// export namespace Y {}
|
||||
|
|
|
|||
|
|
@ -10662,6 +10662,8 @@ pub(crate) const OFFSET_TS_MODULE_DECLARATION_BODY: usize = offset_of!(TSModuleD
|
|||
pub(crate) const OFFSET_TS_MODULE_DECLARATION_KIND: usize = offset_of!(TSModuleDeclaration, kind);
|
||||
pub(crate) const OFFSET_TS_MODULE_DECLARATION_MODIFIERS: usize =
|
||||
offset_of!(TSModuleDeclaration, modifiers);
|
||||
pub(crate) const OFFSET_TS_MODULE_DECLARATION_SCOPE_ID: usize =
|
||||
offset_of!(TSModuleDeclaration, scope_id);
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
|
|
@ -10696,6 +10698,14 @@ impl<'a> TSModuleDeclarationWithoutId<'a> {
|
|||
as *const Modifiers<'a>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scope_id(&self) -> &Cell<Option<ScopeId>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_TS_MODULE_DECLARATION_SCOPE_ID)
|
||||
as *const Cell<Option<ScopeId>>)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
|
|
@ -10731,11 +10741,18 @@ impl<'a> TSModuleDeclarationWithoutBody<'a> {
|
|||
as *const Modifiers<'a>)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scope_id(&self) -> &Cell<Option<ScopeId>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_TS_MODULE_DECLARATION_SCOPE_ID)
|
||||
as *const Cell<Option<ScopeId>>)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const OFFSET_TS_MODULE_BLOCK_SPAN: usize = offset_of!(TSModuleBlock, span);
|
||||
pub(crate) const OFFSET_TS_MODULE_BLOCK_BODY: usize = offset_of!(TSModuleBlock, body);
|
||||
pub(crate) const OFFSET_TS_MODULE_BLOCK_SCOPE_ID: usize = offset_of!(TSModuleBlock, scope_id);
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug)]
|
||||
|
|
@ -10746,14 +10763,6 @@ impl<'a> TSModuleBlockWithoutBody<'a> {
|
|||
pub fn span(&self) -> &Span {
|
||||
unsafe { &*((self.0 as *const u8).add(OFFSET_TS_MODULE_BLOCK_SPAN) as *const Span) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn scope_id(&self) -> &Cell<Option<ScopeId>> {
|
||||
unsafe {
|
||||
&*((self.0 as *const u8).add(OFFSET_TS_MODULE_BLOCK_SCOPE_ID)
|
||||
as *const Cell<Option<ScopeId>>)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const OFFSET_TS_TYPE_LITERAL_SPAN: usize = offset_of!(TSTypeLiteral, span);
|
||||
|
|
|
|||
|
|
@ -4826,6 +4826,15 @@ pub(crate) unsafe fn walk_ts_module_declaration<'a, Tr: Traverse<'a>>(
|
|||
as *mut TSModuleDeclarationName,
|
||||
ctx,
|
||||
);
|
||||
let mut previous_scope_id = None;
|
||||
if let Some(scope_id) = (*((node as *mut u8)
|
||||
.add(ancestor::OFFSET_TS_MODULE_DECLARATION_SCOPE_ID)
|
||||
as *mut Cell<Option<ScopeId>>))
|
||||
.get()
|
||||
{
|
||||
previous_scope_id = Some(ctx.current_scope_id());
|
||||
ctx.set_current_scope_id(scope_id);
|
||||
}
|
||||
if let Some(field) = &mut *((node as *mut u8).add(ancestor::OFFSET_TS_MODULE_DECLARATION_BODY)
|
||||
as *mut Option<TSModuleDeclarationBody>)
|
||||
{
|
||||
|
|
@ -4834,6 +4843,9 @@ pub(crate) unsafe fn walk_ts_module_declaration<'a, Tr: Traverse<'a>>(
|
|||
}
|
||||
ctx.pop_stack();
|
||||
traverser.exit_ts_module_declaration(&mut *node, ctx);
|
||||
if let Some(previous_scope_id) = previous_scope_id {
|
||||
ctx.set_current_scope_id(previous_scope_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn walk_ts_module_declaration_name<'a, Tr: Traverse<'a>>(
|
||||
|
|
@ -4875,14 +4887,6 @@ pub(crate) unsafe fn walk_ts_module_block<'a, Tr: Traverse<'a>>(
|
|||
node: *mut TSModuleBlock<'a>,
|
||||
ctx: &mut TraverseCtx<'a>,
|
||||
) {
|
||||
let mut previous_scope_id = None;
|
||||
if let Some(scope_id) = (*((node as *mut u8).add(ancestor::OFFSET_TS_MODULE_BLOCK_SCOPE_ID)
|
||||
as *mut Cell<Option<ScopeId>>))
|
||||
.get()
|
||||
{
|
||||
previous_scope_id = Some(ctx.current_scope_id());
|
||||
ctx.set_current_scope_id(scope_id);
|
||||
}
|
||||
traverser.enter_ts_module_block(&mut *node, ctx);
|
||||
ctx.push_stack(Ancestor::TSModuleBlockBody(ancestor::TSModuleBlockWithoutBody(node)));
|
||||
walk_statements(
|
||||
|
|
@ -4892,9 +4896,6 @@ pub(crate) unsafe fn walk_ts_module_block<'a, Tr: Traverse<'a>>(
|
|||
);
|
||||
ctx.pop_stack();
|
||||
traverser.exit_ts_module_block(&mut *node, ctx);
|
||||
if let Some(previous_scope_id) = previous_scope_id {
|
||||
ctx.set_current_scope_id(previous_scope_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn walk_ts_type_literal<'a, Tr: Traverse<'a>>(
|
||||
|
|
|
|||
Loading…
Reference in a new issue