From 7b13159cda54b6e2dc5faef02c87ae87daa59237 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 27 May 2017 17:44:59 +0800 Subject: [PATCH] fix `hoist_funs` on block-scoped `function` under "use strict" (#2013) Technically not part of ES5, but commonly used code exists in the wild. --- lib/compress.js | 5 ++- test/compress/functions.js | 78 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 2 deletions(-) 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" +} -- 2.34.1