diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2017-05-27 17:44:59 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-27 17:44:59 +0800 |
commit | 7b13159cda54b6e2dc5faef02c87ae87daa59237 (patch) | |
tree | cbf74885817ef210d58450e5afa871b50e75752e | |
parent | 95094b9c22d5f7b303383f75e660fc32d0a7f25f (diff) | |
download | tracifyjs-7b13159cda54b6e2dc5faef02c87ae87daa59237.tar.gz tracifyjs-7b13159cda54b6e2dc5faef02c87ae87daa59237.zip |
fix `hoist_funs` on block-scoped `function` under "use strict" (#2013)
Technically not part of ES5, but commonly used code exists in the wild.
-rw-r--r-- | lib/compress.js | 5 | ||||
-rw-r--r-- | 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" +} |