transformForInOrOfOrOn_(tree, superMethod, constr) {
    if (!tree.initializer.isPattern() &&
        (tree.initializer.type !== VARIABLE_DECLARATION_LIST ||
         !hasDestructuring(tree.initializer))) {
      return superMethod.call(this, tree);
    }

    this.pushTempScope();

    let declarationType, lvalue;
    if (tree.initializer.isPattern()) {
      declarationType = null;
      lvalue = tree.initializer;
    } else {
      declarationType = tree.initializer.declarationType;
      lvalue = tree.initializer.declarations[0].lvalue;
    }

    // for (var pattern in coll) {
    //
    // =>
    //
    // for (var $tmp in coll) {
    //   var pattern = $tmp;
    //
    // And when the initializer is an assignment expression.
    //
    // for (pattern in coll) {
    //
    // =>
    //
    // for (var $tmp in coll) {
    //   pattern = $tmp;

    let statements = [];
    let binding = this.desugarBinding_(lvalue, statements, declarationType);
    let initializer = createVariableDeclarationList(VAR,
        binding, null);

    let collection = this.transformAny(tree.collection);
    let body = this.transformAny(tree.body);
    if (body.type === BLOCK)
      statements.push(...body.statements);
    else
      statements.push(body);
    body = createBlock(statements);

    this.popTempScope();

    return new constr(tree.location, initializer, collection, body);
  }
Transforms for-in and for-of loops.
@param  {ForInStatement|ForOfStatement} tree The for-in or for-of loop.
@param  {Function} superMethod The super method to call if no pattern is
    present.
@param  {Function} constr The constructor used to create the transformed
    tree.
@return {ForInStatement|ForOfStatement} The transformed tree.
@private