Repository: babel/babili (js)

Issue:
minify-simplify produces invalid code (duplicate symbols)
Hello,

There is a clash when the same symbol exists in the parent and the `else` scopes like in this example (look for the `clash` functions):

#### Input Code

```sh
babel --plugins minify-simplify test.js > simplify.js
```

```js
function test (a) {
  const clash = () => {
    return 'tata';
  };

  if (a) {
    return clash ();
  } else {
    const clash = () => {
      return 'toto';
    };

    return clash ();
  }
}

console.log (test ());
console.log (test (true));
```

#### Actual Output
```sh
simplify.js:10
  };
  ^
SyntaxError: Identifier 'clash' has already been declared
    at createScript (vm.js:56:10)
    at Object.runInThisContext (vm.js:97:10)
    at Module._compile (module.js:542:28)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:389:7)
    at startup (bootstrap_node.js:149:9)
```

```js
function test(a) {
  const clash = () => {
    return 'tata';
  };

  if (a) return clash();

  const clash = () => {
    return 'toto';
  };

  return clash();
}

console.log(test()), console.log(test(true));
```

#### Expected Output (or similar)

```js
function test(a) {
  const clash = () => {
    return 'tata';
  };

  if (a) return clash();

  {
    const clash = () => {
      return 'toto';
    };

    return clash();
  }
}

console.log(test()), console.log(test(true));
```

```
toto
tata
```


Pull request:
Don't remove else with blockscoped decl
Fix #637

Patch:
diff --git a/packages/babel-plugin-minify-simplify/src/if-statement.js b/packages/babel-plugin-minify-simplify/src/if-statement.js
index 37cefc1..61dd213 100644
--- a/packages/babel-plugin-minify-simplify/src/if-statement.js
+++ b/packages/babel-plugin-minify-simplify/src/if-statement.js
@@ -276,7 +276,18 @@ module.exports = t => {
         (consequent.isBlockStatement() &&
           t.isReturnStatement(
             consequent.node.body[consequent.node.body.length - 1]
-          )))
+          ))) &&
+      // don't hoist declarations
+      // TODO: validate declarations after fixing scope issues
+      (alternate.isBlockStatement()
+        ? !alternate
+            .get("body")
+            .some(
+              stmt =>
+                stmt.isVariableDeclaration({ kind: "let" }) ||
+                stmt.isVariableDeclaration({ kind: "const" })
+            )
+        : true)
     ) {
       path.insertAfter(
         alternate.isBlockStatement()


Test patch:
diff --git a/packages/babel-plugin-minify-simplify/__tests__/simplify-test.js b/packages/babel-plugin-minify-simplify/__tests__/simplify-test.js
index 9642c60..9f15e45 100644
--- a/packages/babel-plugin-minify-simplify/__tests__/simplify-test.js
+++ b/packages/babel-plugin-minify-simplify/__tests__/simplify-test.js
@@ -2532,4 +2532,29 @@ describe("simplify-plugin", () => {
       }
     `
   );
+
+  // TODO: issue-637
+  thePlugin(
+    "should NOT remove else block when ",
+    `
+      function test(a) {
+        const clash = () => {};
+        if (a) {
+          return clash();
+        } else {
+          const clash = () => {};
+          return clash();
+        }
+      }
+    `,
+    `
+      function test(a) {
+        const clash = () => {};
+        if (a) return clash();else {
+          const clash = () => {};
+          return clash();
+        }
+      }
+    `
+  );
 });