Skip to content

Commit

Permalink
Fix incorrect public TS class field name minification (#15411)
Browse files Browse the repository at this point in the history
  • Loading branch information
heimskr authored Nov 27, 2024
1 parent 1bb211d commit 7fd16eb
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
14 changes: 10 additions & 4 deletions src/js_parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -21821,21 +21821,27 @@ fn NewParser_(
if (arg.is_typescript_ctor_field) {
switch (arg.binding.data) {
.b_identifier => |id| {
const name = p.symbols.items[id.ref.innerIndex()].original_name;
const ident = p.newExpr(E.Identifier{ .ref = id.ref }, arg.binding.loc);
const arg_symbol = p.symbols.items[id.ref.innerIndex()];
const name = arg_symbol.original_name;
const arg_ident = p.newExpr(E.Identifier{ .ref = id.ref }, arg.binding.loc);

stmts.insert(if (super_index) |k| j + k + 1 else j, Stmt.assign(
p.newExpr(E.Dot{
.target = p.newExpr(E.This{}, arg.binding.loc),
.name = name,
.name_loc = arg.binding.loc,
}, arg.binding.loc),
ident,
arg_ident,
)) catch unreachable;
// O(N)
class_body.items.len += 1;
bun.copy(G.Property, class_body.items[j + 1 ..], class_body.items[j .. class_body.items.len - 1]);
class_body.items[j] = G.Property{ .key = ident };
// Copy the argument name symbol to prevent the class field declaration from being renamed
// but not the constructor argument.
const field_symbol_ref = p.declareSymbol(.other, arg.binding.loc, name) catch id.ref;
field_symbol_ref.getSymbol(p.symbols.items).must_not_be_renamed = true;
const field_ident = p.newExpr(E.Identifier{ .ref = field_symbol_ref }, arg.binding.loc);
class_body.items[j] = G.Property{ .key = field_ident };
j += 1;
},
else => {},
Expand Down
2 changes: 1 addition & 1 deletion src/js_printer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ pub const PrintResult = union(enum) {
// do not make this a packed struct
// stage1 compiler bug:
// > /optional-chain-with-function.js: Evaluation failed: TypeError: (intermediate value) is not a function
// this test failure was caused by the packed structi mplementation
// this test failure was caused by the packed struct implementation
const ExprFlag = enum {
forbid_call,
forbid_in,
Expand Down
21 changes: 21 additions & 0 deletions test/bundler/bundler_edgecase.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2253,4 +2253,25 @@ describe("bundler", () => {
stdout: "windows",
},
});

itBundled("edgecase/TSPublicFieldMinification", {
files: {
"/entry.ts": /* ts */ `
export class Foo {
constructor(public name: string) {}
}
const keys = Object.keys(new Foo('test'))
if (keys.length !== 1) throw new Error('Keys length is not 1')
if (keys[0] !== 'name') throw new Error('keys[0] is not "name"')
console.log('success')
`,
},
minifySyntax: true,
minifyIdentifiers: true,
target: "bun",
run: {
stdout: "success",
},
});
});

0 comments on commit 7fd16eb

Please sign in to comment.