refactor(compiler): reuse import specifier accessors (#28560)

Replace repeated local binding dispatch with import specifier accessors.
Implemented with AI.


---

<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Cam McHenryandCopilot authored and GitHub committed 2026-10-31 00:34:07 -04:00
1 parent b67ad68106
commit 3e43308c63
5 files changed
+22 -72

No files matched your search

+2 -12
View File
@@ -1,7 +1,7 @@
use oxc_ast::ast::{
ArrayPattern, AssignmentPattern, BindingIdentifier, BindingPattern, BindingRestElement, Class,
Declaration, ExportDeclaration, FormalParameter, FormalParameters, Function, ImportDeclaration,
ImportDeclarationSpecifier, ModuleDeclaration, ObjectPattern, VariableDeclaration,
ModuleDeclaration, ObjectPattern, VariableDeclaration,
};
/// [`BoundName`](https://tc39.es/ecma262/#sec-static-semantics-boundnames)
@@ -142,17 +142,7 @@ impl<'a> BoundNames<'a> for ImportDeclaration<'a> {
fn bound_names<F: FnMut(&BindingIdentifier<'a>)>(&self, f: &mut F) {
if let Some(specifiers) = &self.specifiers {
for specifier in specifiers {
match specifier {
ImportDeclarationSpecifier::ImportSpecifier(specifier) => {
f(&specifier.local);
}
ImportDeclarationSpecifier::ImportDefaultSpecifier(specifier) => {
f(&specifier.local);
}
ImportDeclarationSpecifier::ImportNamespaceSpecifier(specifier) => {
f(&specifier.local);
}
}
f(specifier.local());
}
}
}
+1 -11
View File
@@ -155,17 +155,7 @@ impl<'a> IsolatedDeclarations<'a> {
let mut new_specifiers = ArenaVec::with_capacity_in(specifiers.len(), self);
specifiers.iter().for_each(|specifier| {
let is_referenced = match specifier {
ImportDeclarationSpecifier::ImportSpecifier(specifier) => {
self.scope.has_reference(specifier.local.name)
}
ImportDeclarationSpecifier::ImportDefaultSpecifier(specifier) => {
self.scope.has_reference(specifier.local.name)
}
ImportDeclarationSpecifier::ImportNamespaceSpecifier(_) => {
self.scope.has_reference(specifier.name())
}
};
let is_referenced = self.scope.has_reference(specifier.name());
if is_referenced {
new_specifiers.push(specifier.clone_in(self.allocator()));
}
@@ -277,7 +277,7 @@ impl<'a> PeepholeOptimizations {
if let Some(phase) = import_decl.phase {
let (ImportPhase::Defer | ImportPhase::Source) = phase;
if ctx.scoping().symbol_is_unused(
import_decl.specifiers.as_ref().unwrap().first().unwrap().local().symbol_id(),
import_decl.specifiers.as_ref().unwrap().first().unwrap().symbol_id(),
) {
let new_stmt = Statement::new_empty_statement(import_decl.span, ctx);
ctx.replace_statement(stmt, new_stmt);
@@ -292,16 +292,7 @@ impl<'a> PeepholeOptimizations {
let original_len = specifiers.len();
specifiers.retain(|specifier| {
let local = match specifier {
ImportDeclarationSpecifier::ImportSpecifier(s) => &s.local,
ImportDeclarationSpecifier::ImportDefaultSpecifier(s) => &s.local,
ImportDeclarationSpecifier::ImportNamespaceSpecifier(s) => &s.local,
};
let symbol_id = local.symbol_id();
!ctx.scoping().symbol_is_unused(symbol_id)
});
specifiers.retain(|specifier| !ctx.scoping().symbol_is_unused(specifier.symbol_id()));
if specifiers.len() != original_len {
ctx.notice_change();
+9 -12
View File
@@ -209,25 +209,22 @@ impl<'a> ModuleRecordBuilder<'a> {
if let Some(specifiers) = &decl.specifiers {
for specifier in specifiers {
let (import_name, local_name, is_type) = match specifier {
let local = specifier.local();
let local_name = NameSpan::new(local.name.into(), local.span);
let (import_name, is_type) = match specifier {
ImportDeclarationSpecifier::ImportSpecifier(specifier) => (
ImportImportName::Name(NameSpan::new(
specifier.imported.name(),
specifier.imported.span(),
)),
NameSpan::new(specifier.local.name.into(), specifier.local.span),
decl.import_kind.is_type() || specifier.import_kind.is_type(),
),
ImportDeclarationSpecifier::ImportNamespaceSpecifier(specifier) => (
ImportImportName::NamespaceObject,
NameSpan::new(specifier.local.name.into(), specifier.local.span),
decl.import_kind.is_type(),
),
ImportDeclarationSpecifier::ImportDefaultSpecifier(specifier) => (
ImportImportName::Default(specifier.span),
NameSpan::new(specifier.local.name.into(), specifier.local.span),
decl.import_kind.is_type(),
),
ImportDeclarationSpecifier::ImportNamespaceSpecifier(_) => {
(ImportImportName::NamespaceObject, decl.import_kind.is_type())
}
ImportDeclarationSpecifier::ImportDefaultSpecifier(specifier) => {
(ImportImportName::Default(specifier.span), decl.import_kind.is_type())
}
};
self.add_import_entry(ImportEntry {
statement_span: decl.span,
@@ -108,21 +108,13 @@ impl<'a> Traverse<'a, TransformState<'a>> for TypeScriptAnnotations<'a> {
true
} else {
specifiers.retain(|specifier| {
let id = match specifier {
ImportDeclarationSpecifier::ImportSpecifier(s) => {
if s.import_kind.is_type() {
Self::remove_binding(&s.local, ctx);
return false;
}
&s.local
}
ImportDeclarationSpecifier::ImportDefaultSpecifier(s) => {
&s.local
}
ImportDeclarationSpecifier::ImportNamespaceSpecifier(s) => {
&s.local
}
};
if let ImportDeclarationSpecifier::ImportSpecifier(s) = specifier
&& s.import_kind.is_type()
{
Self::remove_binding(&s.local, ctx);
return false;
}
let id = specifier.local();
// If `only_remove_type_imports` is true, then we can return `true` to keep it because
// it is not a type import, otherwise we need to check if the identifier is referenced
if self.only_remove_type_imports || self.has_value_reference(id, ctx) {
@@ -569,17 +561,7 @@ impl<'a> TypeScriptAnnotations<'a> {
fn remove_import_declaration_bindings(decl: &ImportDeclaration<'a>, ctx: &mut TraverseCtx<'a>) {
if let Some(specifiers) = &decl.specifiers {
for specifier in specifiers {
match specifier {
ImportDeclarationSpecifier::ImportSpecifier(specifier) => {
Self::remove_binding(&specifier.local, ctx);
}
ImportDeclarationSpecifier::ImportDefaultSpecifier(specifier) => {
Self::remove_binding(&specifier.local, ctx);
}
ImportDeclarationSpecifier::ImportNamespaceSpecifier(specifier) => {
Self::remove_binding(&specifier.local, ctx);
}
}
Self::remove_binding(specifier.local(), ctx);
}
}
}