mozilla/sweet.js — pull request #204 by natefaubion (2014-01-16 23:13:13+00:00)
Title: Fix name clash for global leaks when using --readable-names

This is a bit of an obscure bug, but can come up if you're using `--readable-names` and messing around with hygiene. Normally, it would result in a `ReferenceError` or something at runtime, but `--readable-names` could mask the issue, resulting in hard to track down bugs.

Take this code:

```js
macro clobber {
case { _ $body } => {
var b = #{ $body };
b[0].context = null;
return b;
}
}

var a = 12;
function foo() {
var a = 1;
var b = clobber a;
return b;
}
```

Normally, this would be compiled as such:

```js
var a$281 = 12;
function foo$282() {
var a$283 = 1;
var b$285 = a;
return b$285;
}
```

Notice the `a` reference doesn't have a hygiene tag because we clobbered it's context. With `--readable-names` this would get expanded to:

```js
var a = 12;
function foo() {
var a$2 = 1;
var b = a;
return b;
}
```

Notice how the `a` in `b = a` would refer to the outer `a`? This PR splits `--readable-names` into two passes on the AST: one to gather all the non-static/global reference, and one to mangle. It will now expand correctly to:

```js
var a$2 = 12;
function foo() {
var a$3 = 1;
var b = a;
return b;
}
```

Preserving the same hygiene as the expansion without `--readable-names`.