From c1381696e8f8e3c14619d08f7b7a3189236b0347 Mon Sep 17 00:00:00 2001 From: Dunqing Date: Fri, 22 Mar 2024 11:24:20 +0800 Subject: [PATCH] feat(semantic): distinguish type imports in ModuleRecord --- crates/oxc_ast/src/ast/js.rs | 1 + crates/oxc_ast/src/ast/ts.rs | 19 +-------------- crates/oxc_ast/src/ast_builder.rs | 1 + crates/oxc_parser/src/js/list.rs | 1 + crates/oxc_parser/src/js/module.rs | 1 + crates/oxc_parser/src/ts/statement.rs | 1 + .../oxc_semantic/src/module_record/builder.rs | 14 +++++++---- crates/oxc_syntax/src/module_record.rs | 24 +++++++++++++++++++ 8 files changed, 40 insertions(+), 22 deletions(-) diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 679190744119..1ede2c4a1317 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -6,6 +6,7 @@ use std::{cell::Cell, fmt, hash::Hash}; use oxc_allocator::{Box, Vec}; use oxc_span::{Atom, CompactStr, SourceType, Span}; use oxc_syntax::{ + module_record::ImportOrExportKind, operator::{ AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator, UpdateOperator, }, diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index 188d11cc11c2..68da2bf6e27e 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -8,6 +8,7 @@ use oxc_allocator::{Box, Vec}; use oxc_span::{Atom, GetSpan, Span}; +use oxc_syntax::module_record::ImportOrExportKind; #[cfg(feature = "serialize")] use serde::Serialize; #[cfg(feature = "serialize")] @@ -1079,24 +1080,6 @@ pub struct TSInstantiationExpression<'a> { pub type_parameters: Box<'a, TSTypeParameterInstantiation<'a>>, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] -#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] -pub enum ImportOrExportKind { - Value, - Type, -} - -impl ImportOrExportKind { - pub fn is_value(&self) -> bool { - matches!(self, Self::Value) - } - - pub fn is_type(&self) -> bool { - matches!(self, Self::Type) - } -} - // [`JSDoc`](https://github.com/microsoft/TypeScript/blob/54a554d8af2657630307cbfa8a3e4f3946e36507/src/compiler/types.ts#L393) #[derive(Debug, Hash)] diff --git a/crates/oxc_ast/src/ast_builder.rs b/crates/oxc_ast/src/ast_builder.rs index a0a4600bca19..c1663a6a2375 100644 --- a/crates/oxc_ast/src/ast_builder.rs +++ b/crates/oxc_ast/src/ast_builder.rs @@ -10,6 +10,7 @@ use std::mem; use oxc_allocator::{Allocator, Box, String, Vec}; use oxc_span::{Atom, GetSpan, SourceType, Span, SPAN}; use oxc_syntax::{ + module_record::ImportOrExportKind, operator::{ AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator, UpdateOperator, }, diff --git a/crates/oxc_parser/src/js/list.rs b/crates/oxc_parser/src/js/list.rs index 133897fbddd9..b6a618a0fcf5 100644 --- a/crates/oxc_parser/src/js/list.rs +++ b/crates/oxc_parser/src/js/list.rs @@ -6,6 +6,7 @@ use oxc_diagnostics::{ Result, }; use oxc_span::{Atom, CompactStr, GetSpan, Span}; +use oxc_syntax::module_record::ImportOrExportKind; use rustc_hash::FxHashMap; use crate::{ diff --git a/crates/oxc_parser/src/js/module.rs b/crates/oxc_parser/src/js/module.rs index 8ddc492a323f..10699b54d295 100644 --- a/crates/oxc_parser/src/js/module.rs +++ b/crates/oxc_parser/src/js/module.rs @@ -2,6 +2,7 @@ use oxc_allocator::{Box, Vec}; use oxc_ast::ast::*; use oxc_diagnostics::Result; use oxc_span::Span; +use oxc_syntax::module_record::ImportOrExportKind; use super::{ function::FunctionKind, diff --git a/crates/oxc_parser/src/ts/statement.rs b/crates/oxc_parser/src/ts/statement.rs index 0cfbcabcc019..1510ebb949a4 100644 --- a/crates/oxc_parser/src/ts/statement.rs +++ b/crates/oxc_parser/src/ts/statement.rs @@ -2,6 +2,7 @@ use oxc_allocator::Box; use oxc_ast::ast::*; use oxc_diagnostics::Result; use oxc_span::Span; +use oxc_syntax::module_record::ImportOrExportKind; use super::{ list::{TSEnumMemberList, TSInterfaceOrObjectBodyList}, diff --git a/crates/oxc_semantic/src/module_record/builder.rs b/crates/oxc_semantic/src/module_record/builder.rs index 29aec61d4dc9..a8ca0b88d37c 100644 --- a/crates/oxc_semantic/src/module_record/builder.rs +++ b/crates/oxc_semantic/src/module_record/builder.rs @@ -170,33 +170,39 @@ impl ModuleRecordBuilder { } fn visit_import_declaration(&mut self, decl: &ImportDeclaration) { - if decl.import_kind.is_type() { - return; - } let module_request = NameSpan::new(decl.source.value.to_compact_str(), decl.source.span); + if let Some(specifiers) = &decl.specifiers { for specifier in specifiers { - let (import_name, local_name) = match specifier { + let (import_name, local_name, import_kind) = match specifier { ImportDeclarationSpecifier::ImportSpecifier(specifier) => ( ImportImportName::Name(NameSpan::new( specifier.imported.name().to_compact_str(), specifier.imported.span(), )), NameSpan::new(specifier.local.name.to_compact_str(), specifier.local.span), + if decl.import_kind.is_type() { + decl.import_kind + } else { + specifier.import_kind + }, ), ImportDeclarationSpecifier::ImportNamespaceSpecifier(specifier) => ( ImportImportName::NamespaceObject, NameSpan::new(specifier.local.name.to_compact_str(), specifier.local.span), + decl.import_kind, ), ImportDeclarationSpecifier::ImportDefaultSpecifier(specifier) => ( ImportImportName::Default(specifier.span), NameSpan::new(specifier.local.name.to_compact_str(), specifier.local.span), + decl.import_kind, ), }; self.add_import_entry(ImportEntry { module_request: module_request.clone(), import_name, local_name, + import_kind, }); } } diff --git a/crates/oxc_syntax/src/module_record.rs b/crates/oxc_syntax/src/module_record.rs index fca0d7c5dace..328e704764b7 100644 --- a/crates/oxc_syntax/src/module_record.rs +++ b/crates/oxc_syntax/src/module_record.rs @@ -5,6 +5,10 @@ use std::{fmt, hash::BuildHasherDefault, path::PathBuf, sync::Arc}; use dashmap::DashMap; use indexmap::IndexMap; use rustc_hash::{FxHashMap, FxHasher}; +#[cfg(feature = "serialize")] +use serde::Serialize; +#[cfg(feature = "serialize")] +use tsify::Tsify; use oxc_span::{CompactStr, Span}; @@ -148,6 +152,8 @@ pub struct ImportEntry { /// The name that is used to locally access the imported value from within the importing module. pub local_name: NameSpan, + + pub import_kind: ImportOrExportKind, } /// `ImportName` For `ImportEntry` @@ -265,6 +271,24 @@ pub struct FunctionMeta { pub deprecated: bool, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] +#[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] +pub enum ImportOrExportKind { + Value, + Type, +} + +impl ImportOrExportKind { + pub fn is_value(&self) -> bool { + matches!(self, Self::Value) + } + + pub fn is_type(&self) -> bool { + matches!(self, Self::Type) + } +} + #[cfg(test)] mod test { use super::{ExportExportName, ExportLocalName, ImportImportName, NameSpan};