From 9f7bedb5680066c79237e85ef30e1849757b55a1 Mon Sep 17 00:00:00 2001 From: alexlamsl Date: Sun, 29 Sep 2024 05:05:45 +0300 Subject: [PATCH] mangle private class properties as local scope closes #5937 --- lib/propmangle.js | 15 ++++++-- test/compress/classes.js | 80 +++++++++++++++++++++++++++++++++++----- 2 files changed, 82 insertions(+), 13 deletions(-) diff --git a/lib/propmangle.js b/lib/propmangle.js index bd1af120ef..07e2714fce 100644 --- a/lib/propmangle.js +++ b/lib/propmangle.js @@ -179,7 +179,7 @@ function mangle_properties(ast, options) { reserved.set(name, true); }); - var cname = -1; + var cname = [ -1, -1 ]; var cache; if (options.cache) { cache = options.cache.props; @@ -245,7 +245,7 @@ function mangle_properties(ast, options) { })); // step 2: renaming properties - ast.walk(new TreeWalker(function(node) { + ast.walk(new TreeWalker(function(node, descend) { if (node instanceof AST_Binary) { if (node.operator == "in") mangleStrings(node.left); } else if (node.TYPE == "Call") { @@ -265,6 +265,12 @@ function mangle_properties(ast, options) { mangleStrings(node.args[0]); break; } + } else if (node instanceof AST_Class) { + var save_cname = cname[1]; + cname[1] = -1; + descend(); + cname[1] = save_cname; + return true; } else if (node instanceof AST_ClassProperty || node instanceof AST_DestructuredKeyVal || node instanceof AST_ObjectProperty) { @@ -331,11 +337,12 @@ function mangle_properties(ast, options) { var debug_mangled = "_$" + name + "$" + debug_suffix + "_"; if (can_mangle(debug_mangled)) mangled = debug_mangled; } + var hash = +/^#/.test(name); // either debug mode is off, or it is on and we could not use the mangled name if (!mangled) do { - mangled = base54(++cname); + mangled = base54(++cname[hash]); } while (!can_mangle(mangled)); - if (/^#/.test(name)) mangled = "#" + mangled; + if (hash) mangled = "#" + mangled; cache.set(name, mangled); } AST_Node.info("Mapping property {name} to {mangled}", { diff --git a/test/compress/classes.js b/test/compress/classes.js index 313e03c377..8bc3f4cee8 100644 --- a/test/compress/classes.js +++ b/test/compress/classes.js @@ -2401,31 +2401,93 @@ mangle_properties: { expect: { class A { static #t = "PASS"; - static get s() { + static get t() { return this.#t; } - #i(t) { - return (this["q"] = t) * this.e; + #s(t) { + return (this["q"] = t) * this.s; } set q(t) { - this.e = t + 1; + this.s = t + 1; } - e = this.#i(6); + s = this.#s(6); } - console.log(A.s, new A().e); + console.log(A.t, new A().s); } expect_stdout: "PASS 42" expect_warnings: [ "INFO: Preserving reserved property q", "INFO: Mapping property #P to #t", - "INFO: Mapping property Q to s", - "INFO: Mapping property #p to #i", - "INFO: Mapping property r to e", + "INFO: Mapping property Q to t", + "INFO: Mapping property #p to #s", + "INFO: Mapping property r to s", "INFO: Preserving reserved property log", ] node_version: ">=14.6" } +mangle_private_local: { + mangle = { + properties: { + domprops: true, + }, + } + input: { + class A { + p = "foo"; + #q = "bar"; + f() { + console.log(this.p, this.#q); + } + } + class B { + #r = "moo"; + #g() { + return "baz"; + } + h() { + console.log(this.#r, this.#g()); + } + } + new A().f(); + new B().h(); + } + expect: { + class A { + s = "foo"; + #s = "bar"; + o() { + console.log(this.s, this.#s); + } + } + class B { + #s = "moo"; + #o() { + return "baz"; + } + e() { + console.log(this.#s, this.#o()); + } + } + new A().o(); + new B().e(); + } + expect_stdout: [ + "foo bar", + "moo baz", + ] + expect_warnings: [ + "INFO: Mapping property p to s", + "INFO: Mapping property #q to #s", + "INFO: Mapping property f to o", + "INFO: Preserving reserved property log", + "INFO: Mapping property #r to #s", + "INFO: Mapping property #g to #o", + "INFO: Mapping property h to e", + ] + node_version: ">=14.6" +} + issue_4848: { options = { if_return: true,