From 3b679cd5d2427a0382815ad40459d6f95109aac0 Mon Sep 17 00:00:00 2001 From: alexlamsl Date: Wed, 17 Jan 2018 14:42:54 +0800 Subject: [PATCH] fix `AST_Scope.clone()` fixes #2799 --- lib/ast.js | 7 +++++++ lib/utils.js | 7 +++++++ test/compress/reduce_vars.js | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/lib/ast.js b/lib/ast.js index 4e41659c..fdd18d69 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -308,6 +308,13 @@ var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes", cname: "[integer/S] current index for mangling variables (used internally by the mangler)", }, + clone: function(deep) { + var node = this._clone(deep); + node.variables = this.variables.clone(); + node.functions = this.functions.clone(); + node.enclosed = this.enclosed.slice(); + return node; + } }, AST_Block); var AST_Toplevel = DEFNODE("Toplevel", "globals", { diff --git a/lib/utils.js b/lib/utils.js index dab7f566..9121fa93 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -303,6 +303,13 @@ Dictionary.prototype = { ret.push(f(this._values[i], i.substr(1))); return ret; }, + clone: function() { + var ret = new Dictionary(); + for (var i in this._values) + ret._values[i] = this._values[i]; + ret._size = this._size; + return ret; + }, toObject: function() { return this._values } }; Dictionary.fromObject = function(obj) { diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js index ec0471a8..5f640df8 100644 --- a/test/compress/reduce_vars.js +++ b/test/compress/reduce_vars.js @@ -5302,3 +5302,37 @@ issue_2774: { } expect_stdout: "undefined" } + +issue_2799: { + options = { + reduce_funcs: true, + reduce_vars: true, + unused: true, + } + input: { + console.log(function() { + return f; + function f(n) { + function g(i) { + return i && i + g(i - 1); + } + function h(j) { + return g(j); + } + return h(n); + } + }()(5)); + } + expect: { + console.log(function() { + return function(n) { + return function(j) { + return function g(i) { + return i && i + g(i - 1); + }(j); + }(n); + } + }()(5)); + } + expect_stdout: "15" +}