Skip to content

Commit

Permalink
Add helper-hoist-variables docs (#2500)
Browse files Browse the repository at this point in the history
* docs: add helper-hoist-variables

* Update helper-hoist-variables.md

* Update docs/helper-hoist-variables.md

Co-authored-by: Brian Ng <bng412@gmail.com>

Co-authored-by: Henry Zhu <hi@henryzoo.com>
Co-authored-by: Brian Ng <bng412@gmail.com>
  • Loading branch information
3 people committed Apr 26, 2021
1 parent b59adeb commit 71e9b45
Showing 1 changed file with 44 additions and 3 deletions.
47 changes: 44 additions & 3 deletions docs/helper-hoist-variables.md
Expand Up @@ -10,11 +10,52 @@ npm install @babel/helper-hoist-variables --save

## API

```javascript
declare export default hoistVariables(path: NodePath, emit: Function, kind: "var" | "let" = "var");
```typescript
type EmitFunction = (
id: t.Identifier,
idName: string,
hasInit: boolean,
) => any;

declare export default hoistVariables(path: NodePath, emit: EmitFunction, kind: "var" | "let" = "var");
```

## Usage

TODO
`hoistVariables` traverses a given `path` and replaces variable declarations (`var x = 1`) with assignment expressions (`x = 1`). It can also replace left hand side expressions `for (x of []);` like in `for (var x of []);`). The binding identifiers (`x`) from the declarations will be emitted via the `EmitFunction` callback. `hoistVariables` is only applied to declarations within the same scope of `path`, in other words, it will _not_ hoist variables defined inside a function body nested inside `path`. If `kind` is `"let"` it will hoist `let` declarations.

Generally an `EmitFunction` will declare such variables in outer `scope`.

## Example

```javascript
import hoistVariables from "@babel/helper-hoist-variables";

// a naive plugin transforms
// `(function myEval(){ var x = 1; })()`
// to
// `var x;(function myEval(){ x = 1; })()`

module.exports = api => {
return {
visitor: {
Function(path) {
if (path.node.id.name === "myEval") {
const outerScope = path.scope.parent;
hoistVariables(
path.get("body"),
id => {
// Use Scope#push to register a `var` binding in
// the outer scope
outerScope.push({ id });
},
"var"
);
}
},
},
};
};
```

`@babel/plugin-proposal-do-expressions` also uses the same technique to hoist the `var` declarations in do blocks to the containing function scope.

0 comments on commit 71e9b45

Please sign in to comment.