feat(hir,minifier): wire up identifier reference for mangle

This commit is contained in:
Boshen 2023-05-13 17:52:25 +08:00
parent ebfaa3b940
commit 48398ea74c
No known key found for this signature in database
GPG key ID: 9C7A8C8AB22BEBD1
6 changed files with 44 additions and 13 deletions

View file

@ -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(

View file

@ -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,
}

View file

@ -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(

View file

@ -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());
}
}
}

View file

@ -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)
}
}

View file

@ -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())
}
}