mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(hir,minifier): wire up identifier reference for mangle
This commit is contained in:
parent
ebfaa3b940
commit
48398ea74c
6 changed files with 44 additions and 13 deletions
|
|
@ -315,12 +315,12 @@ impl<'a> AstLower<'a> {
|
|||
ast::Expression::Super(expr) => self.lower_super(expr),
|
||||
ast::Expression::JSXElement(elem) => {
|
||||
// TODO: implement JSX
|
||||
let ident = self.hir.identifier_reference(elem.span, "undefined".into());
|
||||
let ident = self.hir.identifier_reference(elem.span, "undefined".into(), None);
|
||||
self.hir.identifier_reference_expression(ident)
|
||||
}
|
||||
ast::Expression::JSXFragment(elem) => {
|
||||
// TODO: implement JSX
|
||||
let ident = self.hir.identifier_reference(elem.span, "undefined".into());
|
||||
let ident = self.hir.identifier_reference(elem.span, "undefined".into(), None);
|
||||
self.hir.identifier_reference_expression(ident)
|
||||
}
|
||||
|
||||
|
|
@ -698,7 +698,7 @@ impl<'a> AstLower<'a> {
|
|||
}
|
||||
expr => {
|
||||
// return undefined because this is invalid syntax
|
||||
let ident = self.hir.identifier_reference(expr.span(), "undefined".into());
|
||||
let ident = self.hir.identifier_reference(expr.span(), "undefined".into(), None);
|
||||
self.hir.assignment_target_identifier(ident)
|
||||
}
|
||||
}
|
||||
|
|
@ -915,7 +915,8 @@ impl<'a> AstLower<'a> {
|
|||
&mut self,
|
||||
ident: &ast::IdentifierReference,
|
||||
) -> hir::IdentifierReference {
|
||||
self.hir.identifier_reference(ident.span, ident.name.clone())
|
||||
let symbol_id = self.semantic.enter_identifier_reference(&ident.name);
|
||||
self.hir.identifier_reference(ident.span, ident.name.clone(), symbol_id)
|
||||
}
|
||||
|
||||
fn lower_private_identifier(
|
||||
|
|
|
|||
|
|
@ -370,6 +370,8 @@ pub struct IdentifierReference {
|
|||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub name: Atom,
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
pub symbol_id: Option<SymbolId>,
|
||||
}
|
||||
|
||||
/// Binding Identifier
|
||||
|
|
@ -379,6 +381,7 @@ pub struct BindingIdentifier {
|
|||
#[cfg_attr(feature = "serde", serde(flatten))]
|
||||
pub span: Span,
|
||||
pub name: Atom,
|
||||
#[cfg_attr(feature = "serde", serde(skip))]
|
||||
pub symbol_id: SymbolId,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -174,8 +174,13 @@ impl<'a> HirBuilder<'a> {
|
|||
IdentifierName { span, name }
|
||||
}
|
||||
|
||||
pub fn identifier_reference(&mut self, span: Span, name: Atom) -> IdentifierReference {
|
||||
IdentifierReference { span, name }
|
||||
pub fn identifier_reference(
|
||||
&mut self,
|
||||
span: Span,
|
||||
name: Atom,
|
||||
symbol_id: Option<SymbolId>,
|
||||
) -> IdentifierReference {
|
||||
IdentifierReference { span, name, symbol_id }
|
||||
}
|
||||
|
||||
pub fn binding_identifier(
|
||||
|
|
|
|||
|
|
@ -772,7 +772,11 @@ impl<'a> Gen for Expression<'a> {
|
|||
|
||||
impl Gen for IdentifierReference {
|
||||
fn gen(&self, p: &mut Printer) {
|
||||
p.print_str(self.name.as_bytes());
|
||||
if let Some(symbol_id) = self.symbol_id {
|
||||
p.print_symbol(symbol_id, &self.name);
|
||||
} else {
|
||||
p.print_str(self.name.as_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,11 +62,11 @@ impl SemanticBuilder {
|
|||
|
||||
/// Declares a `Symbol` for the node, adds it to symbol table, and binds it to the scope.
|
||||
///
|
||||
/// includes: the SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.)
|
||||
/// includes: the `SymbolFlags` that node has in addition to its declaration type (eg: export, ambient, etc.)
|
||||
/// excludes: the flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations.
|
||||
///
|
||||
/// Reports errors for conflicting identifier names.
|
||||
pub fn declare_symbol(
|
||||
fn declare_symbol(
|
||||
&mut self,
|
||||
span: Span,
|
||||
name: &Atom,
|
||||
|
|
@ -77,6 +77,12 @@ impl SemanticBuilder {
|
|||
self.scope_tree.get_scope_mut(self.current_scope_id).add_symbol(name.clone(), symbol_id);
|
||||
symbol_id
|
||||
}
|
||||
|
||||
fn resolve_reference(&mut self, name: &Atom) -> Option<SymbolId> {
|
||||
self.scope_tree
|
||||
.ancestors(self.current_scope_id)
|
||||
.find_map(|scope_id| self.scope_tree.get_scope(scope_id).get_binding(name))
|
||||
}
|
||||
}
|
||||
|
||||
impl SemanticBuilder {
|
||||
|
|
@ -85,4 +91,8 @@ impl SemanticBuilder {
|
|||
let excludes = SymbolFlags::FunctionScopedVariableExcludes;
|
||||
self.declare_symbol(span, name, includes, excludes)
|
||||
}
|
||||
|
||||
pub fn enter_identifier_reference(&mut self, name: &Atom) -> Option<SymbolId> {
|
||||
self.resolve_reference(name)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,6 +77,10 @@ impl Scope {
|
|||
self.flags.intersects(ScopeFlags::Function)
|
||||
}
|
||||
|
||||
pub fn get_binding(&self, name: &Atom) -> Option<SymbolId> {
|
||||
self.bindings.get(name).copied()
|
||||
}
|
||||
|
||||
pub fn bindings_entry(&mut self, name: Atom) -> Entry<Atom, SymbolId> {
|
||||
self.bindings.entry(name)
|
||||
}
|
||||
|
|
@ -94,14 +98,14 @@ impl ScopeTree {
|
|||
Self(IndexVec::new())
|
||||
}
|
||||
|
||||
pub fn get_scope(&self, scope_id: ScopeId) -> &Scope {
|
||||
&self.0[scope_id]
|
||||
}
|
||||
|
||||
pub fn root_scope(&self) -> &Scope {
|
||||
self.get_scope(ScopeId::new(0))
|
||||
}
|
||||
|
||||
pub fn get_scope(&self, scope_id: ScopeId) -> &Scope {
|
||||
&self.0[scope_id]
|
||||
}
|
||||
|
||||
pub fn get_scope_mut(&mut self, scope_id: ScopeId) -> &mut Scope {
|
||||
&mut self.0[scope_id]
|
||||
}
|
||||
|
|
@ -109,4 +113,8 @@ impl ScopeTree {
|
|||
pub fn add_scope(&mut self, scope: Scope) -> ScopeId {
|
||||
self.0.push(scope)
|
||||
}
|
||||
|
||||
pub fn ancestors(&self, scope_id: ScopeId) -> impl Iterator<Item = ScopeId> + '_ {
|
||||
std::iter::successors(Some(scope_id), |scope_id| self.get_scope(*scope_id).parent_id())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue