From d571839ab8f0f99fefc9127468a876cf300d4c6b Mon Sep 17 00:00:00 2001 From: Dunqing Date: Mon, 5 Feb 2024 17:43:30 +0800 Subject: [PATCH] feat(ast): enter AstKind::ExportDefaultDeclaration, AstKind::ExportNamedDeclaration and AstKind::ExportAllDeclaration (#2317) --- crates/oxc_ast/src/ast_kind.rs | 9 +++++++++ crates/oxc_ast/src/visit.rs | 13 ++++++++++++- crates/oxc_ast/src/visit_mut.rs | 16 +++++++++++++++- .../src/rules/eslint/no_inner_declarations.rs | 8 +++----- crates/oxc_semantic/src/builder.rs | 12 ++++-------- crates/oxc_semantic/src/checker/javascript.rs | 5 +---- 6 files changed, 44 insertions(+), 19 deletions(-) diff --git a/crates/oxc_ast/src/ast_kind.rs b/crates/oxc_ast/src/ast_kind.rs index fc5e3b84c36e3..92e524adb1257 100644 --- a/crates/oxc_ast/src/ast_kind.rs +++ b/crates/oxc_ast/src/ast_kind.rs @@ -113,6 +113,9 @@ pub enum AstKind<'a> { ImportSpecifier(&'a ImportSpecifier), ImportDefaultSpecifier(&'a ImportDefaultSpecifier), ImportNamespaceSpecifier(&'a ImportNamespaceSpecifier), + ExportDefaultDeclaration(&'a ExportDefaultDeclaration<'a>), + ExportNamedDeclaration(&'a ExportNamedDeclaration<'a>), + ExportAllDeclaration(&'a ExportAllDeclaration<'a>), // JSX // Please make sure to add these to `is_jsx` below. @@ -430,6 +433,9 @@ impl<'a> GetSpan for AstKind<'a> { Self::ImportSpecifier(x) => x.span, Self::ImportDefaultSpecifier(x) => x.span, Self::ImportNamespaceSpecifier(x) => x.span, + Self::ExportDefaultDeclaration(x) => x.span, + Self::ExportNamedDeclaration(x) => x.span, + Self::ExportAllDeclaration(x) => x.span, Self::JSXOpeningElement(x) => x.span, Self::JSXClosingElement(x) => x.span, @@ -615,6 +621,9 @@ impl<'a> AstKind<'a> { Self::ImportSpecifier(_) => "ImportSpecifier".into(), Self::ImportDefaultSpecifier(_) => "ImportDefaultSpecifier".into(), Self::ImportNamespaceSpecifier(_) => "ImportNamespaceSpecifier".into(), + Self::ExportDefaultDeclaration(_) => "ExportDefaultDeclaration".into(), + Self::ExportNamedDeclaration(_) => "ExportNamedDeclaration".into(), + Self::ExportAllDeclaration(_) => "ExportAllDeclaration".into(), Self::JSXOpeningElement(_) => "JSXOpeningElement".into(), Self::JSXClosingElement(_) => "JSXClosingElement".into(), Self::JSXElementName(_) => "JSXElementName".into(), diff --git a/crates/oxc_ast/src/visit.rs b/crates/oxc_ast/src/visit.rs index 183212729e27a..fc1c30237d860 100644 --- a/crates/oxc_ast/src/visit.rs +++ b/crates/oxc_ast/src/visit.rs @@ -1382,9 +1382,16 @@ pub trait Visit<'a>: Sized { self.leave_node(kind); } - fn visit_export_all_declaration(&mut self, _decl: &ExportAllDeclaration<'a>) {} + fn visit_export_all_declaration(&mut self, decl: &ExportAllDeclaration<'a>) { + let kind = AstKind::ExportAllDeclaration(self.alloc(decl)); + self.enter_node(kind); + self.visit_string_literal(&decl.source); + self.leave_node(kind); + } fn visit_export_default_declaration(&mut self, decl: &ExportDefaultDeclaration<'a>) { + let kind = AstKind::ExportDefaultDeclaration(self.alloc(decl)); + self.enter_node(kind); match &decl.declaration { ExportDefaultDeclarationKind::Expression(expr) => self.visit_expression(expr), ExportDefaultDeclarationKind::FunctionDeclaration(func) => { @@ -1393,15 +1400,19 @@ pub trait Visit<'a>: Sized { ExportDefaultDeclarationKind::ClassDeclaration(class) => self.visit_class(class), _ => {} } + self.leave_node(kind); } fn visit_export_named_declaration(&mut self, decl: &ExportNamedDeclaration<'a>) { + let kind = AstKind::ExportNamedDeclaration(self.alloc(decl)); + self.enter_node(kind); if let Some(decl) = &decl.declaration { self.visit_declaration(decl); } if let Some(ref source) = decl.source { self.visit_string_literal(source); } + self.leave_node(kind); } fn visit_enum_member(&mut self, member: &TSEnumMember<'a>) { diff --git a/crates/oxc_ast/src/visit_mut.rs b/crates/oxc_ast/src/visit_mut.rs index 5437002bd8fb4..36760161b2e4a 100644 --- a/crates/oxc_ast/src/visit_mut.rs +++ b/crates/oxc_ast/src/visit_mut.rs @@ -1381,9 +1381,16 @@ pub trait VisitMut<'a>: Sized { self.leave_node(kind); } - fn visit_export_all_declaration(&mut self, _decl: &mut ExportAllDeclaration<'a>) {} + fn visit_export_all_declaration(&mut self, decl: &mut ExportAllDeclaration<'a>) { + let kind = AstKind::ExportAllDeclaration(self.alloc(decl)); + self.enter_node(kind); + self.visit_string_literal(&mut decl.source); + self.leave_node(kind); + } fn visit_export_default_declaration(&mut self, decl: &mut ExportDefaultDeclaration<'a>) { + let kind = AstKind::ExportDefaultDeclaration(self.alloc(decl)); + self.enter_node(kind); match &mut decl.declaration { ExportDefaultDeclarationKind::Expression(expr) => self.visit_expression(expr), ExportDefaultDeclarationKind::FunctionDeclaration(func) => { @@ -1392,12 +1399,19 @@ pub trait VisitMut<'a>: Sized { ExportDefaultDeclarationKind::ClassDeclaration(class) => self.visit_class(class), _ => {} } + self.leave_node(kind); } fn visit_export_named_declaration(&mut self, decl: &mut ExportNamedDeclaration<'a>) { + let kind = AstKind::ExportNamedDeclaration(self.alloc(decl)); + self.enter_node(kind); if let Some(decl) = &mut decl.declaration { self.visit_declaration(decl); } + if let Some(source) = &mut decl.source { + self.visit_string_literal(source); + } + self.leave_node(kind); } fn visit_enum_member(&mut self, member: &mut TSEnumMember<'a>) { diff --git a/crates/oxc_linter/src/rules/eslint/no_inner_declarations.rs b/crates/oxc_linter/src/rules/eslint/no_inner_declarations.rs index 999dd9f3e654b..3292960952432 100644 --- a/crates/oxc_linter/src/rules/eslint/no_inner_declarations.rs +++ b/crates/oxc_linter/src/rules/eslint/no_inner_declarations.rs @@ -1,4 +1,4 @@ -use oxc_ast::{ast::ModuleDeclaration, AstKind}; +use oxc_ast::AstKind; use oxc_diagnostics::{ miette::{self, Diagnostic}, thiserror::Error, @@ -91,10 +91,8 @@ impl Rule for NoInnerDeclarations { parent_kind, AstKind::Program(_) | AstKind::StaticBlock(_) - | AstKind::ModuleDeclaration( - ModuleDeclaration::ExportNamedDeclaration(_) - | ModuleDeclaration::ExportDefaultDeclaration(_) - ) + | AstKind::ExportNamedDeclaration(_) + | AstKind::ExportDefaultDeclaration(_) | AstKind::ForStatementInit(_) | AstKind::ForInStatement(_) | AstKind::ForOfStatement(_) diff --git a/crates/oxc_semantic/src/builder.rs b/crates/oxc_semantic/src/builder.rs index b524dfd6b0b35..a3d59af880ef7 100644 --- a/crates/oxc_semantic/src/builder.rs +++ b/crates/oxc_semantic/src/builder.rs @@ -1641,10 +1641,8 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> { impl<'a> SemanticBuilder<'a> { fn enter_kind(&mut self, kind: AstKind<'a>) { match kind { - AstKind::ModuleDeclaration(decl) => { - if !matches!(decl, ModuleDeclaration::ImportDeclaration(_)) { - self.current_symbol_flags |= SymbolFlags::Export; - } + AstKind::ExportDefaultDeclaration(_) | AstKind::ExportNamedDeclaration(_) => { + self.current_symbol_flags |= SymbolFlags::Export; } AstKind::ImportSpecifier(specifier) => { specifier.bind(self); @@ -1759,10 +1757,8 @@ impl<'a> SemanticBuilder<'a> { self.current_node_flags -= NodeFlags::Class; self.class_table_builder.pop_class(); } - AstKind::ModuleDeclaration(decl) => { - if !matches!(decl, ModuleDeclaration::ImportDeclaration(_)) { - self.current_symbol_flags -= SymbolFlags::Export; - } + AstKind::ExportDefaultDeclaration(_) | AstKind::ExportNamedDeclaration(_) => { + self.current_symbol_flags -= SymbolFlags::Export; } AstKind::LabeledStatement(_) => self.label_builder.leave(), AstKind::StaticBlock(_) | AstKind::Function(_) => { diff --git a/crates/oxc_semantic/src/checker/javascript.rs b/crates/oxc_semantic/src/checker/javascript.rs index e86719ca65836..2bb973f10eed4 100644 --- a/crates/oxc_semantic/src/checker/javascript.rs +++ b/crates/oxc_semantic/src/checker/javascript.rs @@ -762,10 +762,7 @@ fn check_class(class: &Class, node: &AstNode<'_>, ctx: &SemanticBuilder<'_>) { if class.is_declaration() && class.id.is_none() - && !matches!( - ctx.nodes.parent_kind(node.id()), - Some(AstKind::ModuleDeclaration(ModuleDeclaration::ExportDefaultDeclaration(_))) - ) + && !matches!(ctx.nodes.parent_kind(node.id()), Some(AstKind::ExportDefaultDeclaration(_))) { let start = class.span.start; ctx.error(RequireClassName(Span::new(start, start + 5)));