New Upstream Release - node-regenerator-transform

Ready changes

Summary

Merged new upstream version: 0.15.0 (was: 0.14.5).

Resulting package

Built on 2022-05-15T23:51 (took 1m51s)

The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:

apt install -t fresh-releases node-regenerator-transform

Lintian Result

Diff

diff --git a/debian/changelog b/debian/changelog
index bfe2f28..56083c4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+node-regenerator-transform (0.15.0-1) UNRELEASED; urgency=low
+
+  * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sun, 15 May 2022 23:50:15 -0000
+
 node-regenerator-transform (0.14.5-4) unstable; urgency=medium
 
   * Team upload.
diff --git a/debian/patches/fix-babel-config.diff b/debian/patches/fix-babel-config.diff
index a113856..aa3b732 100644
--- a/debian/patches/fix-babel-config.diff
+++ b/debian/patches/fix-babel-config.diff
@@ -4,8 +4,10 @@ Bug-Debian: https://bugs.debian.org/952457
 Forwarded: not-needed
 Last-Update: 2020-02-24
 
---- a/package.json
-+++ b/package.json
+Index: node-regenerator-transform/package.json
+===================================================================
+--- node-regenerator-transform.orig/package.json
++++ node-regenerator-transform/package.json
 @@ -23,12 +23,10 @@
        "@babel/plugin-transform-runtime"
      ],
diff --git a/lib/emit.js b/lib/emit.js
index 87a0390..c26d3a1 100644
--- a/lib/emit.js
+++ b/lib/emit.js
@@ -1,7 +1,5 @@
 "use strict";
 
-var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
-
 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
 
 var _assert = _interopRequireDefault(require("assert"));
@@ -12,6 +10,10 @@ var meta = _interopRequireWildcard(require("./meta"));
 
 var util = _interopRequireWildcard(require("./util"));
 
+function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+
+function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+
 /**
  * Copyright (c) 2014-present, Facebook, Inc.
  *
@@ -583,6 +585,10 @@ Ep.explodeStatement = function (path, labelId) {
       self.emit(t.throwStatement(self.explodeExpression(path.get("argument"))));
       break;
 
+    case "ClassDeclaration":
+      self.emit(self.explodeClass(path));
+      break;
+
     default:
       throw new Error("unknown Statement of type " + JSON.stringify(stmt.type));
   }
@@ -689,6 +695,40 @@ Ep.updateContextPrevLoc = function (loc) {
 
 
   this.emitAssign(this.contextProperty("prev"), loc);
+}; // In order to save the rest of explodeExpression from a combinatorial
+// trainwreck of special cases, explodeViaTempVar is responsible for
+// deciding when a subexpression needs to be "exploded," which is my
+// very technical term for emitting the subexpression as an assignment
+// to a temporary variable and the substituting the temporary variable
+// for the original subexpression. Think of exploded view diagrams, not
+// Michael Bay movies. The point of exploding subexpressions is to
+// control the precise order in which the generated code realizes the
+// side effects of those subexpressions.
+
+
+Ep.explodeViaTempVar = function (tempVar, childPath, hasLeapingChildren, ignoreChildResult) {
+  _assert["default"].ok(!ignoreChildResult || !tempVar, "Ignoring the result of a child expression but forcing it to " + "be assigned to a temporary variable?");
+
+  var t = util.getTypes();
+  var result = this.explodeExpression(childPath, ignoreChildResult);
+
+  if (ignoreChildResult) {// Side effects already emitted above.
+  } else if (tempVar || hasLeapingChildren && !t.isLiteral(result)) {
+    // If tempVar was provided, then the result will always be assigned
+    // to it, even if the result does not otherwise need to be assigned
+    // to a temporary variable.  When no tempVar is provided, we have
+    // the flexibility to decide whether a temporary variable is really
+    // necessary.  Unfortunately, in general, a temporary variable is
+    // required whenever any child contains a yield expression, since it
+    // is difficult to prove (at all, let alone efficiently) whether
+    // this result would evaluate to the same value before and after the
+    // yield (see #206).  One narrow case where we can prove it doesn't
+    // matter (and thus we do not need a temporary variable) is when the
+    // result in question is a Literal value.
+    result = this.emitAssign(tempVar || this.makeTempVar(), result);
+  }
+
+  return result;
 };
 
 Ep.explodeExpression = function (path, ignoreResult) {
@@ -711,9 +751,9 @@ Ep.explodeExpression = function (path, ignoreResult) {
 
     if (ignoreResult) {
       self.emit(expr);
-    } else {
-      return expr;
     }
+
+    return expr;
   } // If the expression does not contain a leap, then we either emit the
   // expression as a standalone statement or return it whole.
 
@@ -726,46 +766,13 @@ Ep.explodeExpression = function (path, ignoreResult) {
   // side effects relative to the leaping child(ren).
 
 
-  var hasLeapingChildren = meta.containsLeap.onlyChildren(expr); // In order to save the rest of explodeExpression from a combinatorial
-  // trainwreck of special cases, explodeViaTempVar is responsible for
-  // deciding when a subexpression needs to be "exploded," which is my
-  // very technical term for emitting the subexpression as an assignment
-  // to a temporary variable and the substituting the temporary variable
-  // for the original subexpression. Think of exploded view diagrams, not
-  // Michael Bay movies. The point of exploding subexpressions is to
-  // control the precise order in which the generated code realizes the
-  // side effects of those subexpressions.
-
-  function explodeViaTempVar(tempVar, childPath, ignoreChildResult) {
-    _assert["default"].ok(!ignoreChildResult || !tempVar, "Ignoring the result of a child expression but forcing it to " + "be assigned to a temporary variable?");
-
-    var result = self.explodeExpression(childPath, ignoreChildResult);
-
-    if (ignoreChildResult) {// Side effects already emitted above.
-    } else if (tempVar || hasLeapingChildren && !t.isLiteral(result)) {
-      // If tempVar was provided, then the result will always be assigned
-      // to it, even if the result does not otherwise need to be assigned
-      // to a temporary variable.  When no tempVar is provided, we have
-      // the flexibility to decide whether a temporary variable is really
-      // necessary.  Unfortunately, in general, a temporary variable is
-      // required whenever any child contains a yield expression, since it
-      // is difficult to prove (at all, let alone efficiently) whether
-      // this result would evaluate to the same value before and after the
-      // yield (see #206).  One narrow case where we can prove it doesn't
-      // matter (and thus we do not need a temporary variable) is when the
-      // result in question is a Literal value.
-      result = self.emitAssign(tempVar || self.makeTempVar(), result);
-    }
-
-    return result;
-  } // If ignoreResult is true, then we must take full responsibility for
+  var hasLeapingChildren = meta.containsLeap.onlyChildren(expr); // If ignoreResult is true, then we must take full responsibility for
   // emitting the expression with all its side effects, and we should not
   // return a result.
 
-
   switch (expr.type) {
     case "MemberExpression":
-      return finish(t.memberExpression(self.explodeExpression(path.get("object")), expr.computed ? explodeViaTempVar(null, path.get("property")) : expr.property, expr.computed));
+      return finish(t.memberExpression(self.explodeExpression(path.get("object")), expr.computed ? self.explodeViaTempVar(null, path.get("property"), hasLeapingChildren) : expr.property, expr.computed));
 
     case "CallExpression":
       var calleePath = path.get("callee");
@@ -784,17 +791,17 @@ Ep.explodeExpression = function (path, ignoreResult) {
           // before evaluating the arguments, but if the callee was a member
           // expression, then we must be careful that the object of the
           // member expression still gets bound to `this` for the call.
-          var newObject = explodeViaTempVar( // Assign the exploded callee.object expression to a temporary
+          var newObject = self.explodeViaTempVar( // Assign the exploded callee.object expression to a temporary
           // variable so that we can use it twice without reevaluating it.
-          self.makeTempVar(), calleePath.get("object"));
-          var newProperty = calleePath.node.computed ? explodeViaTempVar(null, calleePath.get("property")) : calleePath.node.property;
+          self.makeTempVar(), calleePath.get("object"), hasLeapingChildren);
+          var newProperty = calleePath.node.computed ? self.explodeViaTempVar(null, calleePath.get("property"), hasLeapingChildren) : calleePath.node.property;
           injectFirstArg = newObject;
           newCallee = t.memberExpression(t.memberExpression(t.cloneDeep(newObject), newProperty, calleePath.node.computed), t.identifier("call"), false);
         } else {
           newCallee = self.explodeExpression(calleePath);
         }
       } else {
-        newCallee = explodeViaTempVar(null, calleePath);
+        newCallee = self.explodeViaTempVar(null, calleePath, hasLeapingChildren);
 
         if (t.isMemberExpression(newCallee)) {
           // If the callee was not previously a MemberExpression, then the
@@ -811,7 +818,7 @@ Ep.explodeExpression = function (path, ignoreResult) {
 
       if (hasLeapingArgs) {
         newArgs = argsPath.map(function (argPath) {
-          return explodeViaTempVar(null, argPath);
+          return self.explodeViaTempVar(null, argPath, hasLeapingChildren);
         });
         if (injectFirstArg) newArgs.unshift(injectFirstArg);
         newArgs = newArgs.map(function (arg) {
@@ -824,14 +831,14 @@ Ep.explodeExpression = function (path, ignoreResult) {
       return finish(t.callExpression(newCallee, newArgs));
 
     case "NewExpression":
-      return finish(t.newExpression(explodeViaTempVar(null, path.get("callee")), path.get("arguments").map(function (argPath) {
-        return explodeViaTempVar(null, argPath);
+      return finish(t.newExpression(self.explodeViaTempVar(null, path.get("callee"), hasLeapingChildren), path.get("arguments").map(function (argPath) {
+        return self.explodeViaTempVar(null, argPath, hasLeapingChildren);
       })));
 
     case "ObjectExpression":
       return finish(t.objectExpression(path.get("properties").map(function (propPath) {
         if (propPath.isObjectProperty()) {
-          return t.objectProperty(propPath.node.key, explodeViaTempVar(null, propPath.get("value")), propPath.node.computed);
+          return t.objectProperty(propPath.node.key, self.explodeViaTempVar(null, propPath.get("value"), hasLeapingChildren), propPath.node.computed);
         } else {
           return propPath.node;
         }
@@ -840,9 +847,9 @@ Ep.explodeExpression = function (path, ignoreResult) {
     case "ArrayExpression":
       return finish(t.arrayExpression(path.get("elements").map(function (elemPath) {
         if (elemPath.isSpreadElement()) {
-          return t.spreadElement(explodeViaTempVar(null, elemPath.get("argument")));
+          return t.spreadElement(self.explodeViaTempVar(null, elemPath.get("argument"), hasLeapingChildren));
         } else {
-          return explodeViaTempVar(null, elemPath);
+          return self.explodeViaTempVar(null, elemPath, hasLeapingChildren);
         }
       })));
 
@@ -864,7 +871,7 @@ Ep.explodeExpression = function (path, ignoreResult) {
         result = self.makeTempVar();
       }
 
-      var left = explodeViaTempVar(result, path.get("left"));
+      var left = self.explodeViaTempVar(result, path.get("left"), hasLeapingChildren);
 
       if (expr.operator === "&&") {
         self.jumpIfNot(left, after);
@@ -874,7 +881,7 @@ Ep.explodeExpression = function (path, ignoreResult) {
         self.jumpIf(left, after);
       }
 
-      explodeViaTempVar(result, path.get("right"), ignoreResult);
+      self.explodeViaTempVar(result, path.get("right"), hasLeapingChildren, ignoreResult);
       self.mark(after);
       return result;
 
@@ -888,10 +895,10 @@ Ep.explodeExpression = function (path, ignoreResult) {
         result = self.makeTempVar();
       }
 
-      explodeViaTempVar(result, path.get("consequent"), ignoreResult);
+      self.explodeViaTempVar(result, path.get("consequent"), hasLeapingChildren, ignoreResult);
       self.jump(after);
       self.mark(elseLoc);
-      explodeViaTempVar(result, path.get("alternate"), ignoreResult);
+      self.explodeViaTempVar(result, path.get("alternate"), hasLeapingChildren, ignoreResult);
       self.mark(after);
       return result;
 
@@ -901,7 +908,7 @@ Ep.explodeExpression = function (path, ignoreResult) {
       self.explodeExpression(path.get("argument")), !!expr.prefix));
 
     case "BinaryExpression":
-      return finish(t.binaryExpression(expr.operator, explodeViaTempVar(null, path.get("left")), explodeViaTempVar(null, path.get("right"))));
+      return finish(t.binaryExpression(expr.operator, self.explodeViaTempVar(null, path.get("left"), hasLeapingChildren), self.explodeViaTempVar(null, path.get("right"), hasLeapingChildren)));
 
     case "AssignmentExpression":
       if (expr.operator === "=") {
@@ -953,7 +960,40 @@ Ep.explodeExpression = function (path, ignoreResult) {
       self.mark(after);
       return self.contextProperty("sent");
 
+    case "ClassExpression":
+      return finish(self.explodeClass(path));
+
     default:
       throw new Error("unknown Expression of type " + JSON.stringify(expr.type));
   }
+};
+
+Ep.explodeClass = function (path) {
+  var explodingChildren = [];
+
+  if (path.node.superClass) {
+    explodingChildren.push(path.get("superClass"));
+  }
+
+  path.get("body.body").forEach(function (member) {
+    if (member.node.computed) {
+      explodingChildren.push(member.get("key"));
+    }
+  });
+  var hasLeapingChildren = explodingChildren.some(function (child) {
+    return meta.containsLeap(child);
+  });
+
+  for (var i = 0; i < explodingChildren.length; i++) {
+    var child = explodingChildren[i];
+    var isLast = i === explodingChildren.length - 1;
+
+    if (isLast) {
+      child.replaceWith(this.explodeExpression(child));
+    } else {
+      child.replaceWith(this.explodeViaTempVar(null, child, hasLeapingChildren));
+    }
+  }
+
+  return path.node;
 };
\ No newline at end of file
diff --git a/lib/hoist.js b/lib/hoist.js
index 88757d2..86401c3 100644
--- a/lib/hoist.js
+++ b/lib/hoist.js
@@ -1,9 +1,11 @@
 "use strict";
 
-var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
-
 var util = _interopRequireWildcard(require("./util"));
 
+function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+
+function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+
 /**
  * Copyright (c) 2014-present, Facebook, Inc.
  *
diff --git a/lib/replaceShorthandObjectMethod.js b/lib/replaceShorthandObjectMethod.js
index ec8c5d6..43626b8 100644
--- a/lib/replaceShorthandObjectMethod.js
+++ b/lib/replaceShorthandObjectMethod.js
@@ -1,12 +1,14 @@
 "use strict";
 
-var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
-
 exports.__esModule = true;
 exports["default"] = replaceShorthandObjectMethod;
 
 var util = _interopRequireWildcard(require("./util"));
 
+function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+
+function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+
 /**
  * Copyright (c) 2014-present, Facebook, Inc.
  *
diff --git a/lib/visit.js b/lib/visit.js
index fab2d1a..91f8373 100644
--- a/lib/visit.js
+++ b/lib/visit.js
@@ -6,8 +6,6 @@
  */
 "use strict";
 
-var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
-
 var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
 
 var _assert = _interopRequireDefault(require("assert"));
@@ -20,6 +18,10 @@ var _replaceShorthandObjectMethod = _interopRequireDefault(require("./replaceSho
 
 var util = _interopRequireWildcard(require("./util"));
 
+function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
+
+function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
+
 exports.getVisitor = function (_ref) {
   var t = _ref.types;
   return {
diff --git a/package.json b/package.json
index 4f6157e..cd2be19 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
   "name": "regenerator-transform",
   "author": "Ben Newman <bn@cs.stanford.edu>",
   "description": "Explode async and generator functions into a state machine.",
-  "version": "0.14.5",
+  "version": "0.15.0",
   "main": "lib/index.js",
   "keywords": [
     "regenerator",
@@ -12,7 +12,7 @@
   ],
   "repository": {
     "type": "git",
-    "url": "https://github.com/facebook/regenerator/tree/master/packages/regenerator-transform"
+    "url": "https://github.com/facebook/regenerator/tree/master/packages/transform"
   },
   "license": "MIT",
   "scripts": {
diff --git a/src/emit.js b/src/emit.js
index 5c9e830..67b9538 100644
--- a/src/emit.js
+++ b/src/emit.js
@@ -764,6 +764,10 @@ Ep.explodeStatement = function(path, labelId) {
 
     break;
 
+  case "ClassDeclaration":
+    self.emit(self.explodeClass(path));
+    break;
+
   default:
     throw new Error(
       "unknown Statement of type " +
@@ -900,6 +904,50 @@ Ep.updateContextPrevLoc = function(loc) {
   this.emitAssign(this.contextProperty("prev"), loc);
 };
 
+
+// In order to save the rest of explodeExpression from a combinatorial
+// trainwreck of special cases, explodeViaTempVar is responsible for
+// deciding when a subexpression needs to be "exploded," which is my
+// very technical term for emitting the subexpression as an assignment
+// to a temporary variable and the substituting the temporary variable
+// for the original subexpression. Think of exploded view diagrams, not
+// Michael Bay movies. The point of exploding subexpressions is to
+// control the precise order in which the generated code realizes the
+// side effects of those subexpressions.
+Ep.explodeViaTempVar = function(tempVar, childPath, hasLeapingChildren, ignoreChildResult) {
+  assert.ok(
+    !ignoreChildResult || !tempVar,
+    "Ignoring the result of a child expression but forcing it to " +
+      "be assigned to a temporary variable?"
+  );
+  const t = util.getTypes();
+
+  let result = this.explodeExpression(childPath, ignoreChildResult);
+
+  if (ignoreChildResult) {
+    // Side effects already emitted above.
+
+  } else if (tempVar || (hasLeapingChildren &&
+                          !t.isLiteral(result))) {
+    // If tempVar was provided, then the result will always be assigned
+    // to it, even if the result does not otherwise need to be assigned
+    // to a temporary variable.  When no tempVar is provided, we have
+    // the flexibility to decide whether a temporary variable is really
+    // necessary.  Unfortunately, in general, a temporary variable is
+    // required whenever any child contains a yield expression, since it
+    // is difficult to prove (at all, let alone efficiently) whether
+    // this result would evaluate to the same value before and after the
+    // yield (see #206).  One narrow case where we can prove it doesn't
+    // matter (and thus we do not need a temporary variable) is when the
+    // result in question is a Literal value.
+    result = this.emitAssign(
+      tempVar || this.makeTempVar(),
+      result
+    );
+  }
+  return result;
+};
+
 Ep.explodeExpression = function(path, ignoreResult) {
   const t = util.getTypes();
   let expr = path.node;
@@ -917,9 +965,8 @@ Ep.explodeExpression = function(path, ignoreResult) {
     t.assertExpression(expr);
     if (ignoreResult) {
       self.emit(expr);
-    } else {
-      return expr;
     }
+    return expr;
   }
 
   // If the expression does not contain a leap, then we either emit the
@@ -934,48 +981,6 @@ Ep.explodeExpression = function(path, ignoreResult) {
   // side effects relative to the leaping child(ren).
   let hasLeapingChildren = meta.containsLeap.onlyChildren(expr);
 
-  // In order to save the rest of explodeExpression from a combinatorial
-  // trainwreck of special cases, explodeViaTempVar is responsible for
-  // deciding when a subexpression needs to be "exploded," which is my
-  // very technical term for emitting the subexpression as an assignment
-  // to a temporary variable and the substituting the temporary variable
-  // for the original subexpression. Think of exploded view diagrams, not
-  // Michael Bay movies. The point of exploding subexpressions is to
-  // control the precise order in which the generated code realizes the
-  // side effects of those subexpressions.
-  function explodeViaTempVar(tempVar, childPath, ignoreChildResult) {
-    assert.ok(
-      !ignoreChildResult || !tempVar,
-      "Ignoring the result of a child expression but forcing it to " +
-        "be assigned to a temporary variable?"
-    );
-
-    let result = self.explodeExpression(childPath, ignoreChildResult);
-
-    if (ignoreChildResult) {
-      // Side effects already emitted above.
-
-    } else if (tempVar || (hasLeapingChildren &&
-                           !t.isLiteral(result))) {
-      // If tempVar was provided, then the result will always be assigned
-      // to it, even if the result does not otherwise need to be assigned
-      // to a temporary variable.  When no tempVar is provided, we have
-      // the flexibility to decide whether a temporary variable is really
-      // necessary.  Unfortunately, in general, a temporary variable is
-      // required whenever any child contains a yield expression, since it
-      // is difficult to prove (at all, let alone efficiently) whether
-      // this result would evaluate to the same value before and after the
-      // yield (see #206).  One narrow case where we can prove it doesn't
-      // matter (and thus we do not need a temporary variable) is when the
-      // result in question is a Literal value.
-      result = self.emitAssign(
-        tempVar || self.makeTempVar(),
-        result
-      );
-    }
-    return result;
-  }
-
   // If ignoreResult is true, then we must take full responsibility for
   // emitting the expression with all its side effects, and we should not
   // return a result.
@@ -985,7 +990,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
     return finish(t.memberExpression(
       self.explodeExpression(path.get("object")),
       expr.computed
-        ? explodeViaTempVar(null, path.get("property"))
+        ? self.explodeViaTempVar(null, path.get("property"), hasLeapingChildren)
         : expr.property,
       expr.computed
     ));
@@ -1011,15 +1016,16 @@ Ep.explodeExpression = function(path, ignoreResult) {
         // expression, then we must be careful that the object of the
         // member expression still gets bound to `this` for the call.
 
-        let newObject = explodeViaTempVar(
+        let newObject = self.explodeViaTempVar(
           // Assign the exploded callee.object expression to a temporary
           // variable so that we can use it twice without reevaluating it.
           self.makeTempVar(),
-          calleePath.get("object")
+          calleePath.get("object"),
+          hasLeapingChildren
         );
 
         let newProperty = calleePath.node.computed
-          ? explodeViaTempVar(null, calleePath.get("property"))
+          ? self.explodeViaTempVar(null, calleePath.get("property"), hasLeapingChildren)
           : calleePath.node.property;
 
         injectFirstArg = newObject;
@@ -1039,7 +1045,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
       }
 
     } else {
-      newCallee = explodeViaTempVar(null, calleePath);
+      newCallee = self.explodeViaTempVar(null, calleePath, hasLeapingChildren);
 
       if (t.isMemberExpression(newCallee)) {
         // If the callee was not previously a MemberExpression, then the
@@ -1058,7 +1064,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
     }
 
     if (hasLeapingArgs) {
-      newArgs = argsPath.map(argPath => explodeViaTempVar(null, argPath));
+      newArgs = argsPath.map(argPath => self.explodeViaTempVar(null, argPath, hasLeapingChildren));
       if (injectFirstArg) newArgs.unshift(injectFirstArg);
 
       newArgs = newArgs.map(arg => t.cloneDeep(arg));
@@ -1070,9 +1076,9 @@ Ep.explodeExpression = function(path, ignoreResult) {
 
   case "NewExpression":
     return finish(t.newExpression(
-      explodeViaTempVar(null, path.get("callee")),
-      path.get("arguments").map(function(argPath) {
-        return explodeViaTempVar(null, argPath);
+     self.explodeViaTempVar(null, path.get("callee"), hasLeapingChildren),
+       path.get("arguments").map(function(argPath) {
+        return self.explodeViaTempVar(null, argPath, hasLeapingChildren);
       })
     ));
 
@@ -1082,7 +1088,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
         if (propPath.isObjectProperty()) {
           return t.objectProperty(
             propPath.node.key,
-            explodeViaTempVar(null, propPath.get("value")),
+            self.explodeViaTempVar(null, propPath.get("value"), hasLeapingChildren),
             propPath.node.computed
           );
         } else {
@@ -1096,10 +1102,10 @@ Ep.explodeExpression = function(path, ignoreResult) {
       path.get("elements").map(function(elemPath) {
         if (elemPath.isSpreadElement()) {
           return t.spreadElement(
-            explodeViaTempVar(null, elemPath.get("argument"))
+            self.explodeViaTempVar(null, elemPath.get("argument"), hasLeapingChildren)
           );
         } else {
-          return explodeViaTempVar(null, elemPath);
+          return self.explodeViaTempVar(null, elemPath, hasLeapingChildren);
         }
       })
     ));
@@ -1124,7 +1130,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
       result = self.makeTempVar();
     }
 
-    let left = explodeViaTempVar(result, path.get("left"));
+    let left = self.explodeViaTempVar(result, path.get("left"), hasLeapingChildren);
 
     if (expr.operator === "&&") {
       self.jumpIfNot(left, after);
@@ -1133,7 +1139,7 @@ Ep.explodeExpression = function(path, ignoreResult) {
       self.jumpIf(left, after);
     }
 
-    explodeViaTempVar(result, path.get("right"), ignoreResult);
+    self.explodeViaTempVar(result, path.get("right"), hasLeapingChildren, ignoreResult);
 
     self.mark(after);
 
@@ -1150,11 +1156,11 @@ Ep.explodeExpression = function(path, ignoreResult) {
       result = self.makeTempVar();
     }
 
-    explodeViaTempVar(result, path.get("consequent"), ignoreResult);
+    self.explodeViaTempVar(result, path.get("consequent"), hasLeapingChildren, ignoreResult);
     self.jump(after);
 
     self.mark(elseLoc);
-    explodeViaTempVar(result, path.get("alternate"), ignoreResult);
+    self.explodeViaTempVar(result, path.get("alternate"), hasLeapingChildren, ignoreResult);
 
     self.mark(after);
 
@@ -1172,8 +1178,8 @@ Ep.explodeExpression = function(path, ignoreResult) {
   case "BinaryExpression":
     return finish(t.binaryExpression(
       expr.operator,
-      explodeViaTempVar(null, path.get("left")),
-      explodeViaTempVar(null, path.get("right"))
+      self.explodeViaTempVar(null, path.get("left"), hasLeapingChildren),
+      self.explodeViaTempVar(null, path.get("right"), hasLeapingChildren)
     ));
 
   case "AssignmentExpression":
@@ -1254,9 +1260,42 @@ Ep.explodeExpression = function(path, ignoreResult) {
 
     return self.contextProperty("sent");
 
+  case "ClassExpression":
+    return finish(self.explodeClass(path));
+
   default:
     throw new Error(
       "unknown Expression of type " +
         JSON.stringify(expr.type));
   }
 };
+
+Ep.explodeClass = function(path) {
+  const explodingChildren = [];
+
+  if (path.node.superClass) {
+    explodingChildren.push(path.get("superClass"));
+  }
+
+  path.get("body.body").forEach(member => {
+    if (member.node.computed) {
+      explodingChildren.push(member.get("key"));
+    }
+  });
+
+  const hasLeapingChildren = explodingChildren.some(
+    child => meta.containsLeap(child));
+
+  for (let i = 0; i < explodingChildren.length; i++) {
+    const child = explodingChildren[i];
+    const isLast = i === explodingChildren.length - 1;
+
+    if (isLast) {
+      child.replaceWith(this.explodeExpression(child));
+    } else {
+      child.replaceWith(this.explodeViaTempVar(null, child, hasLeapingChildren));
+    }
+  }
+
+  return path.node;
+};

Debdiff

File lists identical (after any substitutions)

No differences were encountered in the control files

More details

Full run details