closure-compiler
closure-compiler copied to clipboard
Unused instances of de-referenced classes are not dead code eliminated
Input:
// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name default.js
// @language_out ECMASCRIPT_2015
// ==/ClosureCompiler==
const A = class {
constructor(opts) {
}
};
new A(1);
Expected output:
'use strict';
Actual output:
'use strict';new class{constructor(){}}(1);
Works as expected with language_out ECMASCRIPT5
,
but any language_out ECMASCRIPT_2015
or above does not DCE the unused instance.
https://closure-compiler.appspot.com/home#code%3D%252F%252F%2520%253D%253DClosureCompiler%253D%253D%250A%252F%252F%2520%2540compilation_level%2520ADVANCED_OPTIMIZATIONS%250A%252F%252F%2520%2540output_file_name%2520default.js%250A%252F%252F%2520%2540language_out%2520ECMASCRIPT_2015%250A%252F%252F%2520%253D%253D%252FClosureCompiler%253D%253D%250A%250Aconst%2520A%2520%253D%2520class%2520%257B%250A%2520%2520constructor(opts)%2520%257B%250A%2520%2520%257D%250A%257D%253B%250A%250Anew%2520A(1)%253B%250A%250Aclass%2520B%2520%257B%250A%2520%2520constructor(opts)%2520%257B%250A%2520%2520%257D%250A%257D%250A%250Anew%2520B(2)%253B%250A%250Aconsole.log(1)%253B%250A
By using --print_source_after_each_pass
I found that after transpilation and inlining the compiler converts the code above to new function(){}(1);
for ES5 output or new class {constructor(){}}(1);
.
Then the peepholeOptimizations
pass knows how to remove new function(){}(1);
, but apparently does not know it is safe to remove new class {constructor(){}}(1);
.