mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
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:
1 parent
b67ad68106
commit
3e43308c63
5 files changed
+22
-72
No files matched your search
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user