Skip to content

Commit

Permalink
fix(mangler): no shorthand BindingProperty; handle var hoisting and…
Browse files Browse the repository at this point in the history
… export variables
  • Loading branch information
Boshen committed Jul 17, 2024
1 parent 5d17675 commit ba684a3
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 23 deletions.
17 changes: 7 additions & 10 deletions crates/oxc_codegen/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,7 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ModuleExportName<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
match self {
Self::IdentifierName(identifier) => p.print_str(identifier.name.as_str()),
Self::IdentifierReference(identifier) => p.print_str(identifier.name.as_str()),
Self::IdentifierReference(identifier) => identifier.gen(p, ctx),
Self::StringLiteral(literal) => literal.gen(p, ctx),
};
}
Expand Down Expand Up @@ -2538,22 +2538,19 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for ObjectPattern<'a> {
}
}

// NOTE: `shorthand` is not printed
impl<'a, const MINIFY: bool> Gen<MINIFY> for BindingProperty<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
p.add_source_mapping(self.span.start);
if self.computed {
p.print_char(b'[');
}
if !self.shorthand {
self.key.gen(p, ctx);
}
self.key.gen(p, ctx);
if self.computed {
p.print_char(b']');
}
if !self.shorthand {
p.print_colon();
p.print_soft_space();
}
p.print_colon();
p.print_soft_space();
self.value.gen(p, ctx);
}
}
Expand Down Expand Up @@ -2959,8 +2956,8 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSTypeLiteral<'a> {
impl<'a, const MINIFY: bool> Gen<MINIFY> for TSTypeName<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
match self {
Self::IdentifierReference(decl) => {
p.print_str(decl.name.as_str());
Self::IdentifierReference(ident) => {
ident.gen(p, ctx);
}
Self::QualifiedName(decl) => {
decl.left.gen(p, ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ input_file: crates/oxc_isolated_declarations/tests/fixtures/function-parameters.
export declare function fnDeclGood(p?: T, rParam?: string): void;
export declare function fnDeclGood2(p?: T, rParam?: number): void;
export declare function fooGood([a, b]?: any[]): number;
export declare const fooGood2: ({ a, b }?: object) => number;
export declare function fooGood3({ a, b: [{ c }] }: object): void;
export declare const fooGood2: ({ a: a, b: b }?: object) => number;
export declare function fooGood3({ a: a, b: [{ c: c }] }: object): void;
export declare function fnDeclBad<T>(p: T, rParam: T, r2: T): void;
export declare function fnDeclBad2<T>(p: T, r2: T): void;
export declare function fnDeclBad3<T>(p: T, rParam?: T, r2: T): void;
Expand Down
5 changes: 3 additions & 2 deletions crates/oxc_mangler/examples/mangler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ fn main() -> std::io::Result<()> {
println!("{printed}");

if twice {
let printed = mangler(&printed, source_type, debug);
println!("{printed}");
let printed2 = mangler(&printed, source_type, debug);
println!("{printed2}");
println!("same = {}", printed == printed2);
}

Ok(())
Expand Down
26 changes: 17 additions & 9 deletions crates/oxc_mangler/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ impl ManglerBuilder {

#[must_use]
pub fn build<'a>(self, program: &'a Program<'a>) -> Mangler {
let semantic_ret = SemanticBuilder::new("", program.source_type).build(program);
let semantic = semantic_ret.semantic;
let semantic = SemanticBuilder::new("", program.source_type).build(program).semantic;

// Mangle the symbol table by computing slots from the scope tree.
// A slot is the occurrence index of a binding identifier inside a scope.
Expand All @@ -101,10 +100,21 @@ impl ManglerBuilder {
.get_parent_id(scope_id)
.map_or(0, |parent_scope_id| max_slot_for_scope[parent_scope_id.index()]);

let parent_bindings = scope_tree
.get_parent_id(scope_id)
.map(|parent_scope_id| scope_tree.get_bindings(parent_scope_id));

let mut slot = parent_max_slot;

// `bindings` are stored in order, traverse and increment slot
for symbol_id in bindings.values() {
// omit var hoisting because var symbols are added to every parent scope
if let Some(parent_bindings) = &parent_bindings {
if parent_bindings.values().contains(symbol_id) {
continue;
}
}

slots[*symbol_id] = slot;
slot += 1;
}
Expand All @@ -119,12 +129,8 @@ impl ManglerBuilder {
let frequencies =
Self::tally_slot_frequencies(&symbol_table, total_number_of_slots, &slots);

let unresolved_references = scope_tree
.root_unresolved_references()
.keys()
// It is unlike to get a 5 letter mangled identifier, which is a lot of slots.
// .filter(|name| name.len() < 5)
.collect::<Vec<_>>();
let unresolved_references =
scope_tree.root_unresolved_references().keys().collect::<Vec<_>>();

let mut names = Vec::with_capacity(total_number_of_slots);

Expand Down Expand Up @@ -195,7 +201,9 @@ impl ManglerBuilder {
) -> Vec<SlotFrequency> {
let mut frequencies = vec![SlotFrequency::default(); total_number_of_slots];
for (symbol_id, slot) in slots.iter_enumerated() {
if !symbol_table.get_flag(symbol_id).is_variable() {
let symbol_flag = symbol_table.get_flag(symbol_id);
// omit renaming `export { x }`
if !symbol_flag.is_variable() || symbol_flag.is_export() {
continue;
}
let index = *slot;
Expand Down

0 comments on commit ba684a3

Please sign in to comment.