From: Alex Lam S.L Date: Sat, 27 May 2017 09:44:59 +0000 (+0800) Subject: fix `hoist_funs` on block-scoped `function` under "use strict" (#2013) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=7b13159cda54b6e2dc5faef02c87ae87daa59237;p=UglifyJS.git fix `hoist_funs` on block-scoped `function` under "use strict" (#2013) Technically not part of ES5, but commonly used code exists in the wild. --- diff --git a/lib/compress.js b/lib/compress.js index efa8e988..6359696b 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2251,11 +2251,12 @@ merge(Compressor.prototype, { dirs.push(node); return make_node(AST_EmptyStatement, node); } - if (node instanceof AST_Defun && hoist_funs) { + if (hoist_funs && node instanceof AST_Defun + && (tt.parent() === self || !compressor.has_directive("use strict"))) { hoisted.push(node); return make_node(AST_EmptyStatement, node); } - if (node instanceof AST_Var && hoist_vars) { + if (hoist_vars && node instanceof AST_Var) { node.definitions.forEach(function(def){ vars.set(def.name.name, def); ++vars_found; diff --git a/test/compress/functions.js b/test/compress/functions.js index 3a560f00..ce8bab80 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -167,3 +167,81 @@ function_returning_constant_literal: { } expect_stdout: "Hello there" } + +hoist_funs: { + options = { + hoist_funs: true, + } + input: { + console.log(1, typeof f, typeof g); + if (console.log(2, typeof f, typeof g)) + console.log(3, typeof f, typeof g); + else { + console.log(4, typeof f, typeof g); + function f() {} + console.log(5, typeof f, typeof g); + } + function g() {} + console.log(6, typeof f, typeof g); + } + expect: { + function f() {} + function g() {} + console.log(1, typeof f, typeof g); + if (console.log(2, typeof f, typeof g)) + console.log(3, typeof f, typeof g); + else { + console.log(4, typeof f, typeof g); + console.log(5, typeof f, typeof g); + } + console.log(6, typeof f, typeof g); + } + expect_stdout: [ + "1 'function' 'function'", + "2 'function' 'function'", + "4 'function' 'function'", + "5 'function' 'function'", + "6 'function' 'function'", + ] + node_version: "<=4" +} + +hoist_funs_strict: { + options = { + hoist_funs: true, + } + input: { + "use strict"; + console.log(1, typeof f, typeof g); + if (console.log(2, typeof f, typeof g)) + console.log(3, typeof f, typeof g); + else { + console.log(4, typeof f, typeof g); + function f() {} + console.log(5, typeof f, typeof g); + } + function g() {} + console.log(6, typeof f, typeof g); + } + expect: { + "use strict"; + function g() {} + console.log(1, typeof f, typeof g); + if (console.log(2, typeof f, typeof g)) + console.log(3, typeof f, typeof g); + else { + console.log(4, typeof f, typeof g); + function f() {} + console.log(5, typeof f, typeof g); + } + console.log(6, typeof f, typeof g); + } + expect_stdout: [ + "1 'undefined' 'function'", + "2 'undefined' 'function'", + "4 'function' 'function'", + "5 'function' 'function'", + "6 'undefined' 'function'", + ] + node_version: "=4" +}