* Add failing test of function parameter bindings in a catch block.
This test can be run in isolation via the following command:
TEST_GREP='block-scoping.*function in catch' make test-only
This test fails because BlockScoping#getLetReferences accidentally
considers the parameters of the function declaration as let bindings in
the catch scope. When the name of the catch parameter is the same as one
of the function's parameter names, the function declaration will be
unnecessarily wrapped to isolate its parameters from the outer scope.
While the extra wrapping may not seem harmful in this case, this behavior
is a symptom of a deeper problem that causes very subtle bugs in transform
code involving catch parameters and function declarations. This test case
was just the simplest example I could find to demonstrate the problem.
I have a proposed fix for this problem that I will push as soon as the
tests fail for this commit.
* Make BlockScoping#getLetReferences ignore function parameters.
When block scoped variables caused the block to be wrapped in a closure, the variable `bindings` remained in parent function scope, which caused the JSX element to be hoisted out of the closure.
I had deleted the binding and created a new one. I naively thought that
the analysis will automatically run again. But now discovered the method
I actually want to use: `scope.moveBindingTo` which moves the binding
and all the correct analysis. The only thing that was left to do is to
update `binding.kind` which I did manually.
I previously tried an approach to scope bindings from var to scope but
it didn't catch all cases. This is evident in this bug:
https://phabricator.babeljs.io/T2892
Where even after transforming a const to a var we still get an error
that it's read-only.
This approach will go through and delete every existing let and const
binding and creates a new one with the kind "var"
When convert a const, let or any other block-bound binding to a var we
forget to update the scope info. This confuses other transforms that may
come after this as to which scope does the binding belongs to.
This also uncovered an issue where duplicate block-scoped bindings were allowed
to co-exist.