mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 20:28:58 +00:00
refactor(syntax): clean up ModuleRecord (#7568)
This commit is contained in:
parent
bf16668de7
commit
79014ffb1d
6 changed files with 41 additions and 48 deletions
|
|
@ -129,8 +129,8 @@ impl Rule for NoDuplicateImports {
|
|||
|
||||
for (source, requests) in &module_record.requested_modules {
|
||||
for request in requests {
|
||||
if request.is_import() && module_record.import_entries.is_empty() {
|
||||
side_effect_import_map.entry(source).or_default().push(request.span());
|
||||
if request.is_import && module_record.import_entries.is_empty() {
|
||||
side_effect_import_map.entry(source).or_default().push(request.span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ impl Rule for NoCycle {
|
|||
});
|
||||
|
||||
if visitor_result.result {
|
||||
let span = module_record.requested_modules[&stack[0].0][0].span();
|
||||
let span = module_record.requested_modules[&stack[0].0][0].span;
|
||||
let help = stack
|
||||
.iter()
|
||||
.map(|(specifier, path)| {
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ impl Rule for NoDuplicates {
|
|||
let requested_modules = group
|
||||
.into_iter()
|
||||
.flat_map(|(_path, requested_modules)| requested_modules)
|
||||
.filter(|requested_module| requested_module.is_import());
|
||||
.filter(|requested_module| requested_module.is_import);
|
||||
// When prefer_inline is false, 0 is value, 1 is type named, 2 is type namespace and 3 is type default
|
||||
// When prefer_inline is true, 0 is value and type named, 2 is type // namespace and 3 is type default
|
||||
let mut import_entries_maps: FxHashMap<u8, Vec<&RequestedModule>> =
|
||||
|
|
@ -116,7 +116,7 @@ impl Rule for NoDuplicates {
|
|||
let imports = module_record
|
||||
.import_entries
|
||||
.iter()
|
||||
.filter(|entry| entry.module_request.span() == requested_module.span())
|
||||
.filter(|entry| entry.module_request.span() == requested_module.span)
|
||||
.collect::<Vec<_>>();
|
||||
if imports.is_empty() {
|
||||
import_entries_maps.entry(0).or_default().push(requested_module);
|
||||
|
|
@ -154,7 +154,7 @@ impl Rule for NoDuplicates {
|
|||
fn check_duplicates(ctx: &LintContext, requested_modules: Option<&Vec<&RequestedModule>>) {
|
||||
if let Some(requested_modules) = requested_modules {
|
||||
if requested_modules.len() > 1 {
|
||||
let mut labels = requested_modules.iter().map(|m| m.span());
|
||||
let mut labels = requested_modules.iter().map(|m| m.span);
|
||||
let first = labels.next().unwrap(); // we know there is at least one
|
||||
let module_name = ctx.source_range(first).trim_matches('\'').trim_matches('"');
|
||||
ctx.diagnostic(no_duplicates_diagnostic(module_name, first, labels));
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ impl Rule for NoSelfImport {
|
|||
};
|
||||
if remote_module_record_ref.value().resolved_absolute_path == *resolved_absolute_path {
|
||||
for requested_module in requested_modules {
|
||||
ctx.diagnostic(no_self_import_diagnostic(requested_module.span()));
|
||||
ctx.diagnostic(no_self_import_diagnostic(requested_module.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,8 +56,8 @@ impl Rule for NoImportNodeTest {
|
|||
|
||||
if let Some(node_test_module) = module_record.requested_modules.get("node:test") {
|
||||
if let Some(requested_module) = node_test_module.first() {
|
||||
ctx.diagnostic_with_fix(no_import_node_test(requested_module.span()), |fixer| {
|
||||
fixer.replace(requested_module.span(), "\"vitest\"")
|
||||
ctx.diagnostic_with_fix(no_import_node_test(requested_module.span), |fixer| {
|
||||
fixer.replace(requested_module.span, "\"vitest\"")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
//! [ECMAScript Module Record](https://tc39.es/ecma262/#sec-abstract-module-records)
|
||||
#![allow(missing_docs)] // fixme
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use oxc_allocator::{Allocator, Vec};
|
||||
use oxc_span::{Atom, Span};
|
||||
|
|
@ -15,6 +12,7 @@ use rustc_hash::FxHashMap;
|
|||
/// See
|
||||
/// * <https://tc39.es/ecma262/#table-additional-fields-of-source-text-module-records>
|
||||
/// * <https://tc39.es/ecma262/#cyclic-module-record>
|
||||
#[derive(Debug)]
|
||||
pub struct ModuleRecord<'a> {
|
||||
/// This module has no import / export statements
|
||||
pub not_esm: bool,
|
||||
|
|
@ -74,6 +72,7 @@ pub struct ModuleRecord<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ModuleRecord<'a> {
|
||||
/// Constructor
|
||||
pub fn new(allocator: &'a Allocator) -> Self {
|
||||
Self {
|
||||
not_esm: true,
|
||||
|
|
@ -91,30 +90,18 @@ impl<'a> ModuleRecord<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for ModuleRecord<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("ModuleRecord")
|
||||
.field("not_esm", &self.not_esm)
|
||||
.field("import_entries", &self.import_entries)
|
||||
.field("local_export_entries", &self.local_export_entries)
|
||||
.field("indirect_export_entries", &self.indirect_export_entries)
|
||||
.field("star_export_entries", &self.star_export_entries)
|
||||
.field("exported_bindings", &self.exported_bindings)
|
||||
.field("exported_bindings_duplicated", &self.exported_bindings_duplicated)
|
||||
.field("exported_bindings_from_star_export", &self.exported_bindings_from_star_export)
|
||||
.field("export_default", &self.export_default)
|
||||
.field("export_default_duplicated", &self.export_default_duplicated)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Name and Span
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct NameSpan<'a> {
|
||||
/// Name
|
||||
pub name: Atom<'a>,
|
||||
|
||||
/// Span
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl<'a> NameSpan<'a> {
|
||||
/// Constructor
|
||||
pub fn new(name: Atom<'a>, span: Span) -> Self {
|
||||
Self { name, span }
|
||||
}
|
||||
|
|
@ -193,16 +180,21 @@ pub struct ImportEntry<'a> {
|
|||
/// `ImportName` For `ImportEntry`
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub enum ImportImportName<'a> {
|
||||
/// Name
|
||||
Name(NameSpan<'a>),
|
||||
/// Namespace Object
|
||||
NamespaceObject,
|
||||
/// Default
|
||||
Default(Span),
|
||||
}
|
||||
|
||||
impl ImportImportName<'_> {
|
||||
/// Is `default`
|
||||
pub fn is_default(&self) -> bool {
|
||||
matches!(self, Self::Default(_))
|
||||
}
|
||||
|
||||
/// Is namespace
|
||||
pub fn is_namespace_object(&self) -> bool {
|
||||
matches!(self, Self::NamespaceObject)
|
||||
}
|
||||
|
|
@ -253,6 +245,7 @@ pub struct ExportEntry<'a> {
|
|||
/// `ImportName` for `ExportEntry`
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub enum ExportImportName<'a> {
|
||||
/// Name
|
||||
Name(NameSpan<'a>),
|
||||
/// all is used for export * as ns from "mod" declarations.
|
||||
All,
|
||||
|
|
@ -263,11 +256,14 @@ pub enum ExportImportName<'a> {
|
|||
Null,
|
||||
}
|
||||
|
||||
/// Export Import Name
|
||||
impl ExportImportName<'_> {
|
||||
/// Is all
|
||||
pub fn is_all(&self) -> bool {
|
||||
matches!(self, Self::All)
|
||||
}
|
||||
|
||||
/// Is all but default
|
||||
pub fn is_all_but_default(&self) -> bool {
|
||||
matches!(self, Self::AllButDefault)
|
||||
}
|
||||
|
|
@ -276,8 +272,11 @@ impl ExportImportName<'_> {
|
|||
/// `ExportName` for `ExportEntry`
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub enum ExportExportName<'a> {
|
||||
/// Name
|
||||
Name(NameSpan<'a>),
|
||||
/// Default
|
||||
Default(Span),
|
||||
/// Null
|
||||
#[default]
|
||||
Null,
|
||||
}
|
||||
|
|
@ -306,9 +305,11 @@ impl ExportExportName<'_> {
|
|||
/// `LocalName` for `ExportEntry`
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
pub enum ExportLocalName<'a> {
|
||||
/// Name
|
||||
Name(NameSpan<'a>),
|
||||
/// `export default name_span`
|
||||
Default(NameSpan<'a>),
|
||||
/// Null
|
||||
#[default]
|
||||
Null,
|
||||
}
|
||||
|
|
@ -333,22 +334,11 @@ impl<'a> ExportLocalName<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// RequestedModule
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct RequestedModule {
|
||||
span: Span,
|
||||
is_type: bool,
|
||||
/// is_import is true if the module is requested by an import statement.
|
||||
is_import: bool,
|
||||
}
|
||||
|
||||
impl RequestedModule {
|
||||
pub fn new(span: Span, is_type: bool, is_import: bool) -> Self {
|
||||
Self { span, is_type, is_import }
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
/// Span
|
||||
pub span: Span,
|
||||
|
||||
/// `true` if a `type` modifier was used in the import statement.
|
||||
///
|
||||
|
|
@ -358,13 +348,16 @@ impl RequestedModule {
|
|||
/// import { type bar } from "bar"; // false, `type` is on specifier
|
||||
/// import { baz } from "baz"; // false, no `type` modifier
|
||||
/// ```
|
||||
pub fn is_type(&self) -> bool {
|
||||
self.is_type
|
||||
}
|
||||
pub is_type: bool,
|
||||
|
||||
/// `true` if the module is requested by an import statement.
|
||||
pub fn is_import(&self) -> bool {
|
||||
self.is_import
|
||||
pub is_import: bool,
|
||||
}
|
||||
|
||||
impl RequestedModule {
|
||||
/// Constructor
|
||||
pub fn new(span: Span, is_type: bool, is_import: bool) -> Self {
|
||||
Self { span, is_type, is_import }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue