-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
This is related to issue #3622 but is another variant of it.
Tested with Closure compiler v20200614
In some circumstances, Closure Compiler will redeclare a local function in a scope block with var
, i.e.:
"use strict";
{
function foo() { ... }
}
will become:
"use strict";
{
var foo = function () { ... }
}
In the first example foo
is scoped to just that block. This behavior appears to be specific to strict mode (which is in use in this example) - in sloppy mode foo
is indeed a global declaration. In the second example the var
has global scope even in strict mode. This causes it to conflict with other places a similar transformation has been done.
For example consider these two input scripts:
// simple1.js
"use strict";
{
function foo(p) { window["external1"](p) }
const local = window["getThing"]();
console.log(foo(local));
console.log(foo(local));
}
// simple2.js
"use strict";
{
function foo(p) { window["external2"](p) }
const local = window["getThing"]();
console.log(foo(local));
console.log(foo(local));
}
Command: java -jar ./closure-compiler.jar --js in.js --js_output_file out.js --compilation_level SIMPLE --language_in ECMASCRIPT_2015 --language_out ECMASCRIPT_2015 --strict_mode_input --formatting PRETTY_PRINT
(update in.js as necessary)
Note these both use a function named foo
, but each calls a different external function. In both cases in simple mode, Closure Compiler replaces the scoped function foo
with var foo = ...
. This means the declaration in simple2.js overwrites the declaration from simple1.js, since they're both global. Then simple1.js ends up calling the wrong foo
implementation, breaking code.
This also gets worse in ADVANCED mode since it's then also possible that functions with different names are renamed to the same short name, e.g. functions foo
and bar
both being redeclared as var a = function () ...
.
To avoid all this happening, Closure Compiler should not redeclare functions in scope blocks with var
in strict mode.