google / google/closure-compiler

`var` is not hoisted to the nearest variable scope

Open
#4,123 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
7.7k
Forks
1.2k
Avg merge
2d 12h
Merged PRs (30d)
6

Description

input code:
```ts
function foo(arg) {
switch(arg.type){
case 'foo':
var _arg_foo;
(_arg_foo = arg.foo) === null || _arg_foo === void 0 ? void 0 : _arg_foo.foo();
break;
case 'bar':
var _arg_foo1;
(_arg_foo1 = arg.foo) === null || _arg_foo1 === void 0 ? void 0 : _arg_foo1.bar();
break;
case 'baz':
var _arg_foo2;
(_arg_foo2 = arg.foo) === null || _arg_foo2 === void 0 ? void 0 : _arg_foo2.baz();
break;
}
}
console.log(foo);
```
Note: [input code is the generated by swc downlevelling optional chaining](https://play.swc.rs/?version=1.3.84&code=H4sIAAAAAAAAA32LMQ6DMBAE%2B3vFdpiGB0DBW4x1EATyIdtREhB%2FzzmhQCJKs9KOZvi5SEjo796lUTx6EWPDUGIjID7G5G7IoEqvhb8UcDYyClWL%2BvOBbOhv85iyOWgX2E4NnZrOhmuj8H%2Bz%2FmrWSwPstBM58VFmrmYZjLpqvQG2xFvC5QAAAA%3D%3D&config=H4sIAAAAAAAAA2WNQQrCQAxF9z1FydqFutOtpfcI07SMjJ2Sn4Kl9O7OKFMUF4HkPchbq7qmOxxd6zWt6ZhYIbrfiWAZjZ%2BJkC2TwKmfjA7FGrLqOUB21omLyhYVSZnO8hbbx5OxDmL5n%2BB8PF2ocOURfdTHd3yGNNL7Udqot8BA6yV0%2BEsGGdgtTQn%2FdKs82wsFyeqG6wAAAA%3D%3D)

[Actual CC output:](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%2540formatting%2520pretty_print%250A%252F%252F%2520%2540language_out%2520ECMASCRIPT_2019%250A%252F%252F%2520%253D%253D%252FClosureCompiler%253D%253D%250A%250A%252F%252F%2520ADD%2520YOUR%2520CODE%2520HERE%250Afunction%2520foo(arg)%2520%257B%250A%2520%2520switch(arg.type)%257B%250A%2520%2520%2520%2520%2520%2520case%2520'foo'%253A%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520var%2520_arg_foo%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520(_arg_foo%2520%253D%2520arg.foo)%2520%253D%253D%253D%2520null%2520%257C%257C%2520_arg_foo%2520%253D%253D%253D%2520void%25200%2520%253F%2520void%25200%2520%253A%2520_arg_foo.foo()%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520break%253B%250A%2520%2520%2520%2520%2520%2520case%2520'bar'%253A%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520var%2520_arg_foo1%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520(_arg_foo1%2520%253D%2520arg.foo)%2520%253D%253D%253D%2520null%2520%257C%257C%2520_arg_foo1%2520%253D%253D%253D%2520void%25200%2520%253F%2520void%25200%2520%253A%2520_arg_foo1.bar()%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520break%253B%250A%2520%2520%2520%2520%2520%2520case%2520'baz'%253A%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520var%2520_arg_foo2%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520(_arg_foo2%2520%253D%2520arg.foo)%2520%253D%253D%253D%2520null%2520%257C%257C%2520_arg_foo2%2520%253D%253D%253D%2520void%25200%2520%253F%2520void%25200%2520%253A%2520_arg_foo2.baz()%253B%250A%2520%2520%2520%2520%2520%2520%2520%2520%2520%2520break%253B%250A%2520%2520%257D%250A%257D%250Aconsole.log(foo)%253B%250A)
```ts
console.log(function(a) {
switch(a.type) {
case "foo":
var b;
null === (b = a.g) || void 0 === b ? void 0 : b.g();
break;
case "bar":
var c;
null === (c = a.g) || void 0 === c ? void 0 : c.h();
break;
case "baz":
var d;
null === (d = a.g) || void 0 === d ? void 0 : d.i();
}
});
```

Expected CC output:
```ts
console.log(function(a) {
var b,c,d;
switch(a.type) {
case "foo":
null === (b = a.g) || void 0 === b ? void 0 : b.g();
break;
case "bar":
null === (c = a.g) || void 0 === c ? void 0 : c.h();
break;
case "baz":
null === (d = a.g) || void 0 === d ? void 0 : d.i();
}
});
```

CC does not hoist the `var`s to the nearest variable scope, even though (as I understand it) it should be runtime equivalent to do so.
If it did hoist the variables then it could collapse them into a single declaration and save the additional `var ` per variable - which would leads to +4b per variable declared within the same variable scope.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.