From 7a796c4b5f1abdd235873e9f3bbd0305d1df9ab7 Mon Sep 17 00:00:00 2001 From: Boshen Date: Sat, 24 Feb 2024 17:09:31 +0800 Subject: [PATCH] feat(ast): add `TSModuleDeclaration.kind` (#2487) closes #2395 --- crates/oxc_ast/src/ast/ts.rs | 19 ++++++++++ crates/oxc_ast/src/ast_builder.rs | 3 +- crates/oxc_parser/src/ts/statement.rs | 51 +++++++++++---------------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index 95ea36d98..6c0b9b7e9 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -703,10 +703,29 @@ pub struct TSModuleDeclaration<'a> { pub span: Span, pub id: TSModuleDeclarationName, pub body: TSModuleDeclarationBody<'a>, + /// The keyword used to define this module declaration + /// ```text + /// namespace Foo {} + /// ^^^^^^^^^ + /// module 'foo' {} + /// ^^^^^^ + /// declare global {} + /// ^^^^^^ + /// ``` + pub kind: TSModuleDeclarationKind, /// Valid Modifiers: `declare`, `export` pub modifiers: Modifiers<'a>, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(Serialize), serde(rename_all = "lowercase"))] +#[cfg_attr(all(feature = "serde", feature = "wasm"), derive(tsify::Tsify))] +pub enum TSModuleDeclarationKind { + Global, + Module, + Namespace, +} + #[derive(Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize), serde(untagged))] #[cfg_attr(all(feature = "serde", feature = "wasm"), derive(tsify::Tsify))] diff --git a/crates/oxc_ast/src/ast_builder.rs b/crates/oxc_ast/src/ast_builder.rs index 9aee870d9..7483b806a 100644 --- a/crates/oxc_ast/src/ast_builder.rs +++ b/crates/oxc_ast/src/ast_builder.rs @@ -1212,9 +1212,10 @@ impl<'a> AstBuilder<'a> { span: Span, id: TSModuleDeclarationName, body: TSModuleDeclarationBody<'a>, + kind: TSModuleDeclarationKind, modifiers: Modifiers<'a>, ) -> Box<'a, TSModuleDeclaration<'a>> { - self.alloc(TSModuleDeclaration { span, id, body, modifiers }) + self.alloc(TSModuleDeclaration { span, id, body, kind, modifiers }) } pub fn ts_type_annotation( diff --git a/crates/oxc_parser/src/ts/statement.rs b/crates/oxc_parser/src/ts/statement.rs index bb1d4f757..cddc4e572 100644 --- a/crates/oxc_parser/src/ts/statement.rs +++ b/crates/oxc_parser/src/ts/statement.rs @@ -250,6 +250,7 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_ts_namespace_or_module_declaration_body( &mut self, span: Span, + kind: TSModuleDeclarationKind, modifiers: Modifiers<'a>, ) -> Result>> { let id = match self.cur_kind() { @@ -260,7 +261,7 @@ impl<'a> ParserImpl<'a> { let body = if self.eat(Kind::Dot) { let span = self.start_span(); let decl = - self.parse_ts_namespace_or_module_declaration_body(span, Modifiers::empty())?; + self.parse_ts_namespace_or_module_declaration_body(span, kind, Modifiers::empty())?; TSModuleDeclarationBody::TSModuleDeclaration(decl) } else { let block = self.parse_ts_module_block()?; @@ -268,24 +269,7 @@ impl<'a> ParserImpl<'a> { TSModuleDeclarationBody::TSModuleBlock(block) }; - Ok(self.ast.ts_module_declaration(self.end_span(span), id, body, modifiers)) - } - - pub(crate) fn parse_ts_namespace_or_module_declaration( - &mut self, - modifiers: Modifiers<'a>, - ) -> Result>> { - let span = self.start_span(); - self.expect(Kind::Namespace).or_else(|_| self.expect(Kind::Module))?; - self.parse_ts_namespace_or_module_declaration_body(span, modifiers) - } - - pub(crate) fn parse_ts_global_declaration( - &mut self, - start_span: Span, - modifiers: Modifiers<'a>, - ) -> Result>> { - self.parse_ts_namespace_or_module_declaration_body(start_span, modifiers) + Ok(self.ast.ts_module_declaration(self.end_span(span), id, body, kind, modifiers)) } /** ----------------------- declare --------------------- */ @@ -308,18 +292,25 @@ impl<'a> ParserImpl<'a> { modifiers: Modifiers<'a>, ) -> Result> { match self.cur_kind() { - Kind::Namespace | Kind::Module => self - .parse_ts_namespace_or_module_declaration(modifiers) - .map(Declaration::TSModuleDeclaration), + Kind::Namespace => { + let kind = TSModuleDeclarationKind::Namespace; + let span = self.start_span(); + self.bump_any(); + self.parse_ts_namespace_or_module_declaration_body(span, kind, modifiers) + .map(Declaration::TSModuleDeclaration) + } + Kind::Module => { + let kind = TSModuleDeclarationKind::Module; + let span = self.start_span(); + self.bump_any(); + self.parse_ts_namespace_or_module_declaration_body(span, kind, modifiers) + .map(Declaration::TSModuleDeclaration) + } Kind::Global => { - let decl = if self.peek_at(Kind::LCurly) { - // valid syntax for - // declare global { } - self.parse_ts_namespace_or_module_declaration_body(start_span, modifiers) - } else { - self.parse_ts_global_declaration(start_span, modifiers) - }?; - Ok(Declaration::TSModuleDeclaration(decl)) + // declare global { } + let kind = TSModuleDeclarationKind::Global; + self.parse_ts_namespace_or_module_declaration_body(start_span, kind, modifiers) + .map(Declaration::TSModuleDeclaration) } Kind::Type => self.parse_ts_type_alias_declaration(start_span, modifiers), Kind::Enum => self.parse_ts_enum_declaration(start_span, modifiers),