babel / babel/babel

[Bug]: plugin-transform-block-scoping constant checks treats deconstruction incorrectly

Open
#13,252 14 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
44k
Forks
6k
Avg merge
5d 15h
Merged PRs (30d)
23

Description

### 💻

- [ ] Would you like to work on a fix?

### How are you using Babel?

@babel/cli

### Input code

```js
const c = 0;
let x = 1, y = 2;
try {
[x, c, y] = [11, 0, 22];
} catch (e) {
console.log( { x, y } );
}
```

[REPL](https://babeljs.io/repl#?browsers=&build=&builtIns=false&corejs=3.6&spec=false&loose=true&code_lz=MYewdgzgLgBMMF4YAYDcAoANgU1gD0RgEYAaGAT0ICYMoAnSgb3RhgG08zgzyBdQtkVIoyVKrwwBfOAEMowABYwAFNgCUMZq1CQQOAHSYQAc2WNOFSWqnogA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=false&fileSize=false&timeTravel=false&sourceType=module&lineWrap=true&presets=&prettier=false&targets=Node-10&version=7.14.0&externalPlugins=%40babel%2Fplugin-transform-block-scoping%407.13.16)

### Configuration file name

_No response_

### Configuration

_No response_

### Current and expected behavior

`[x, c, y] = [11, 0, 22]` is transformed to `[11, 0, 22], _readOnlyError("c")`.

Original logs `{x: 11, y: 2}` whereas transpiled code logs `{x: 1, y: 2}`. It should assign to `x` before throwing, but not assign to `c` or `y`.

### Environment

Babel REPL

### Possible solution

Best solution I can see is:

```js
// Assignments to `c` and `y` have been removed
[x] = [11, 0, 22], _readOnlyError("c");
```

If there's a nested object/array on the receiving end of the assignment, all elements before the const-violating identifier should be retained, and all after it removed - at all levels of the nested object/array.

i.e.: if `c` is a const:

Input: `[ p, q, { r: [ ...s ], t: [ u, c, v ], w, ...x }, y, ...z ] = arr;`
Output: `[ p, q, { r: [ ...s ], t: [ u ] } ] = arr, _readOnlyError("c");`

(note `c`, `v`, `w`, `x`, `y` and `z` have all been removed)

NB `c` may also have a default e.g. `{ c = 1 } = {}`

### Additional context

#13248 fixed some other cases where const violations were transformed incorrectly, but didn't fix this one.

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the example in the Babel REPL with @babel/plugin-transform-block-scoping and compare the original and transformed output. Done means assignments before the const violation are preserved, the violating and later targets are excluded, and nested destructuring and defaults behave consistently.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.