refactor(linter): clean up APIs for ModuleRecord (#7556)

This commit is contained in:
Boshen 2024-12-01 04:48:42 +00:00
parent c2ced15dfd
commit 823353a6fc
13 changed files with 45 additions and 54 deletions

View file

@ -1,5 +1,4 @@
//! [ECMAScript Module Record](https://tc39.es/ecma262/#sec-abstract-module-records)
#![allow(missing_docs)] // fixme
use std::{
fmt,
@ -124,7 +123,7 @@ impl fmt::Debug for ModuleRecord {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NameSpan {
name: CompactStr,
pub name: CompactStr,
span: Span,
}
@ -133,11 +132,11 @@ impl NameSpan {
Self { name, span }
}
pub const fn name(&self) -> &CompactStr {
&self.name
pub fn name(&self) -> &str {
self.name.as_str()
}
pub const fn span(&self) -> Span {
pub fn span(&self) -> Span {
self.span
}
}
@ -413,9 +412,9 @@ impl ExportLocalName {
}
/// Get the bound name of this export. [`None`] for [`ExportLocalName::Null`].
pub const fn name(&self) -> Option<&CompactStr> {
pub fn name(&self) -> Option<&str> {
match self {
Self::Name(name) | Self::Default(name) => Some(name.name()),
Self::Name(name) | Self::Default(name) => Some(name.name.as_str()),
Self::Null => None,
}
}

View file

@ -92,7 +92,7 @@ impl Rule for NoDuplicateImports {
let mut side_effect_import_map: FxHashMap<&CompactStr, Vec<Span>> = FxHashMap::default();
for entry in &module_record.import_entries {
let source = entry.module_request.name();
let source = &entry.module_request.name;
let span = entry.module_request.span();
let same_statement = if let Some(curr_span) = current_span {
@ -153,7 +153,7 @@ impl Rule for NoDuplicateImports {
if self.include_exports {
for entry in &module_record.star_export_entries {
if let Some(module_request) = &entry.module_request {
let source = module_request.name();
let source = &module_request.name;
let span = entry.span;
if entry.import_name.is_all_but_default() {
@ -208,7 +208,7 @@ impl Rule for NoDuplicateImports {
for entry in &module_record.indirect_export_entries {
if let Some(module_request) = &entry.module_request {
let source = module_request.name();
let source = &module_request.name;
let span = entry.span;
if let Some(existing) = import_map.get(source) {

View file

@ -106,25 +106,25 @@ impl Rule for Named {
continue;
}
let import_span = import_name.span();
let import_name = import_name.name();
let name = import_name.name();
// Check `import { default as foo } from 'bar'`
if import_name.as_str() == "default" && remote_module_record.export_default.is_some() {
if name == "default" && remote_module_record.export_default.is_some() {
continue;
}
// Check remote bindings
if remote_module_record.exported_bindings.contains_key(import_name) {
if remote_module_record.exported_bindings.contains_key(name) {
continue;
}
// check re-export
if remote_module_record
.exported_bindings_from_star_export
.iter()
.any(|entry| entry.value().contains(import_name))
.any(|entry| entry.value().contains(&import_name.name))
{
continue;
}
ctx.diagnostic(named_diagnostic(import_name, specifier, import_span));
ctx.diagnostic(named_diagnostic(name, specifier, import_span));
}
for export_entry in &module_record.indirect_export_entries {
@ -146,7 +146,7 @@ impl Rule for Named {
// Check remote bindings
let name = import_name.name();
// `export { default as foo } from './source'` <> `export default xxx`
if *name == "default" && remote_module_record.export_default.is_some() {
if name == "default" && remote_module_record.export_default.is_some() {
continue;
}
if remote_module_record.exported_bindings.contains_key(name) {

View file

@ -155,8 +155,7 @@ impl Rule for Namespace {
return;
}
let Some(symbol_id) = ctx.scopes().get_root_binding(entry.local_name.name().as_str())
else {
let Some(symbol_id) = ctx.scopes().get_root_binding(entry.local_name.name()) else {
return;
};
@ -235,16 +234,15 @@ fn get_module_request_name(name: &str, module_record: &ModuleRecord) -> Option<S
module_record.indirect_export_entries.iter().find(|e| match &e.import_name {
ExportImportName::All => {
if let ExportExportName::Name(name_span) = &e.export_name {
return name_span.name().as_str() == name;
return name_span.name() == name;
}
false
}
ExportImportName::Name(name_span) => {
name_span.name().as_str() == name
name_span.name() == name
&& module_record.import_entries.iter().any(|entry| {
entry.local_name.name().as_str() == name
&& entry.import_name.is_namespace_object()
entry.local_name.name() == name && entry.import_name.is_namespace_object()
})
}
_ => false,
@ -256,9 +254,7 @@ fn get_module_request_name(name: &str, module_record: &ModuleRecord) -> Option<S
module_record
.import_entries
.iter()
.find(|entry| {
entry.local_name.name().as_str() == name && entry.import_name.is_namespace_object()
})
.find(|entry| entry.local_name.name() == name && entry.import_name.is_namespace_object())
.map(|entry| entry.module_request.name().to_string())
}

View file

@ -90,16 +90,13 @@ impl Rule for NoNamedAsDefaultMember {
continue;
}
let Some(symbol_id) =
ctx.scopes().get_root_binding(import_entry.local_name.name().as_str())
let Some(symbol_id) = ctx.scopes().get_root_binding(import_entry.local_name.name())
else {
return;
};
has_members_map.insert(
symbol_id,
(remote_module_record_ref, import_entry.module_request.name().clone()),
);
has_members_map
.insert(symbol_id, (remote_module_record_ref, import_entry.module_request.clone()));
}
if has_members_map.is_empty() {
@ -134,7 +131,7 @@ impl Rule for NoNamedAsDefaultMember {
},
&ident.name,
prop_str,
module_name,
module_name.name(),
));
};
};
@ -161,7 +158,7 @@ impl Rule for NoNamedAsDefaultMember {
decl.span,
&ident.name,
&name,
module_name,
module_name.name(),
));
}
}

View file

@ -37,7 +37,7 @@ impl Rule for NoMocksImport {
let module_records = ctx.module_record();
for import_entry in &module_records.import_entries {
let module_specifier = import_entry.module_request.name().as_str();
let module_specifier = import_entry.module_request.name();
if contains_mocks_dir(module_specifier) {
ctx.diagnostic(no_mocks_import_diagnostic(import_entry.module_request.span()));
}

View file

@ -73,7 +73,7 @@ impl Rule for NoBeforeInteractiveScriptOutsideDocument {
return;
}
let next_script_import_local_name = get_next_script_import_local_name(ctx);
if !matches!(next_script_import_local_name, Some(import) if tag_name.as_str() == import.as_str())
if !matches!(next_script_import_local_name, Some(import) if tag_name == import)
{
return;
}

View file

@ -107,10 +107,12 @@ fn is_inside_export_default(node: &AstNode<'_>, ctx: &LintContext<'_>) -> bool {
let Some(name) = name else {
continue;
};
if ctx.module_record().local_export_entries.iter().any(|e| {
e.local_name.is_default()
&& e.local_name.name().is_some_and(|n| n.as_str() == name.as_str())
}) {
if ctx
.module_record()
.local_export_entries
.iter()
.any(|e| e.local_name.is_default() && e.local_name.name().is_some_and(|n| n == name))
{
is_inside_export_default = true;
}
}

View file

@ -117,8 +117,7 @@ impl Rule for NoUnwantedPolyfillio {
if tag_name.as_str() != "script" {
let next_script_import_local_name = get_next_script_import_local_name(ctx);
if !matches!(next_script_import_local_name, Some(import) if tag_name.as_str() == import.as_str())
{
if !matches!(next_script_import_local_name, Some(import) if tag_name == import) {
return;
}
}

View file

@ -98,8 +98,8 @@ pub fn import_matcher<'a>(
) -> bool {
let expected_module_name = expected_module_name.cow_to_lowercase();
ctx.module_record().import_entries.iter().any(|import| {
import.module_request.name().as_str() == expected_module_name
&& import.local_name.name().as_str() == actual_local_name
import.module_request.name() == expected_module_name
&& import.local_name.name() == actual_local_name
})
}

View file

@ -81,7 +81,7 @@ fn is_inside_process_event_handler(ctx: &LintContext, node: &AstNode) -> bool {
fn is_worker_threads_imported(ctx: &LintContext) -> bool {
ctx.module_record().import_entries.iter().any(|entry| {
matches!(entry.module_request.name().as_str(), "worker_threads" | "node:worker_threads")
matches!(entry.module_request.name(), "worker_threads" | "node:worker_threads")
})
}

View file

@ -1,5 +1,3 @@
use oxc_span::CompactStr;
use crate::LintContext;
pub fn is_in_app_dir(file_path: &str) -> bool {
@ -13,9 +11,9 @@ pub fn is_document_page(file_path: &str) -> bool {
page.starts_with("/_document") || page.starts_with("\\_document")
}
pub fn get_next_script_import_local_name<'a>(ctx: &'a LintContext) -> Option<&'a CompactStr> {
pub fn get_next_script_import_local_name<'a>(ctx: &'a LintContext) -> Option<&'a str> {
ctx.module_record().import_entries.iter().find_map(|entry| {
if entry.module_request.name().as_str() == "next/script" {
if entry.module_request.name() == "next/script" {
Some(entry.local_name.name())
} else {
None

View file

@ -184,18 +184,18 @@ impl PartialEq<CompactStr> for str {
}
}
impl PartialEq<str> for CompactStr {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
}
}
impl PartialEq<CompactStr> for Cow<'_, str> {
fn eq(&self, other: &CompactStr) -> bool {
self.as_ref() == other.as_str()
}
}
impl PartialEq<str> for CompactStr {
fn eq(&self, other: &str) -> bool {
self.as_str() == other
}
}
impl Index<Span> for CompactStr {
type Output = str;