Repository: babel/minify (js)

Issue:
Boolean return statements are changed to (un)defined by minify-simplify
#### Input Code

```js
function(object, property, value) {
    if (object && property) {
        object[property] = value;
        return true;
    }
    return false;
}
```

#### Actual Output
<!-- If an error is thrown, please provide the stack trace here -->

```js
return object && property && (object[property] = value, true);
```

#### Expected Output

```js
return !!(object && property && (object[property]=value));
```

#### Details
When a function returns true/false conditionally based on check of input parameters, this seems to be flattened into a single condition using logical operator && in between. Because of that the result of the above function behaves differently in case when input arguments (object, property) are not provided by the client call.

Calling the function originally with no parameters returns "false".
Calling the function after being transformed by minify-simplify with no parameters returns "undefined".

Pull request:
fix(simplify): fix conditional expression pattern match transformation logic
Fix #689 

Patch:
diff --git a/packages/babel-plugin-minify-dead-code-elimination/src/index.js b/packages/babel-plugin-minify-dead-code-elimination/src/index.js
index 25fe626..037fcce 100644
--- a/packages/babel-plugin-minify-dead-code-elimination/src/index.js
+++ b/packages/babel-plugin-minify-dead-code-elimination/src/index.js
@@ -208,6 +208,14 @@ module.exports = ({ types: t, traverse }) => {
             ) {
               // `bar(function foo() {})` foo is not referenced but it's used.
               continue;
+            } else if (
+              // ClassDeclaration has binding in two scopes
+              //   1. The scope in which it is declared
+              //   2. The class's own scope
+              binding.path.isClassDeclaration() &&
+              binding.path === scope.path
+            ) {
+              continue;
             }
 
             const mutations = [];
diff --git a/packages/babel-plugin-minify-simplify/src/conditional-expression.js b/packages/babel-plugin-minify-simplify/src/conditional-expression.js
index deb980e..17dfc8a 100644
--- a/packages/babel-plugin-minify-simplify/src/conditional-expression.js
+++ b/packages/babel-plugin-minify-simplify/src/conditional-expression.js
@@ -31,7 +31,7 @@ module.exports = t => {
 
       [EX, EX, true, (e, c) => or(not(e), c)],
 
-      [LE, EX, false, (e, c) => and(e, c)],
+      [LE, EX, false, (e, c) => and(notnot(e), c)],
       [EX, EX, false, (e, c) => and(notnot(e), c)]
     ]);
 


Test patch:
diff --git a/packages/babel-plugin-minify-dead-code-elimination/__tests__/fixtures/toplevel-class/actual.js b/packages/babel-plugin-minify-dead-code-elimination/__tests__/fixtures/toplevel-class/actual.js
new file mode 100644
index 0000000..4e6a6de
--- /dev/null
+++ b/packages/babel-plugin-minify-dead-code-elimination/__tests__/fixtures/toplevel-class/actual.js
@@ -0,0 +1,1 @@
+class Foo {}
diff --git a/packages/babel-plugin-minify-dead-code-elimination/__tests__/fixtures/toplevel-class/expected.js b/packages/babel-plugin-minify-dead-code-elimination/__tests__/fixtures/toplevel-class/expected.js
new file mode 100644
index 0000000..f72abf3
--- /dev/null
+++ b/packages/babel-plugin-minify-dead-code-elimination/__tests__/fixtures/toplevel-class/expected.js
@@ -0,0 +1,1 @@
+class Foo {}
\ No newline at end of file
diff --git a/packages/babel-plugin-minify-simplify/__tests__/simplify-test.js b/packages/babel-plugin-minify-simplify/__tests__/simplify-test.js
index 4f1ee36..ade42b6 100644
--- a/packages/babel-plugin-minify-simplify/__tests__/simplify-test.js
+++ b/packages/babel-plugin-minify-simplify/__tests__/simplify-test.js
@@ -1969,6 +1969,36 @@ describe("simplify-plugin", () => {
   `
   );
 
+  thePlugin(
+    "should simplify common conditional operations 2",
+    `
+      function h1() { return a && b ? (foo(), true) : false }
+    `,
+    `
+      function h1() {
+        return !!(a && b) && (foo(), true);
+      }
+    `
+  );
+
+  thePlugin(
+    "should fix issue#689",
+    `
+      function foo(object, property, value) {
+        if (object && property) {
+          object[property] = value;
+          return true;
+        }
+        return false;
+      }
+    `,
+    `
+      function foo(object, property, value) {
+        return !!(object && property) && (object[property] = value, true);
+      }
+    `
+  );
+
   // From UglifyJS
   thePlugin.inEachLine(
     "should simplify logical expression of the following forms of && by compressing to the right",